# Trying to debug Pop/PushMatrix -- Can I see the stack?

**URL:** https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170
**Category:** Processing.py
**Created:** [June 26, 2020, 2:12am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170 "2020-06-26T02:12:03Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![slashwreck](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@slashwreck](https://discourse.processing.org/u/slashwreck)
#### Post date: [June 26, 2020, 2:12am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/1 "2020-06-26T02:12:03Z")

</div>

I had some working code, added some simple translation, and now I’m getting `missing a pushMatrix()` error. I believe all my `push`, `pop`, and `translate` commands are balanced, so I don’t see where the error is.

Is there a way to viewthe size of the matrix stack (eg. `len(matrixStack)` so I can isolate where the problem occurs?

I took my code, removed most of the work, and left the matrix-related commands in – I don’t see where I’m unbalanced, `pop`ing more matrices than I `push`. Or else maybe I am missing some basic concept of how this is supposed to work.

The idea is: Start with A4-size page, translate in by a border margin, then iterate through some smaller cells on the upper part of the document, then translate back to the original border-margin point, and retranslate to a point farther down the page.

```auto
def setup():
    noLoop()

    #initial alignment for Dish Block
    translate(0,0) # (redundant)
    pushMatrix() #store the default reference frame
    translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX)

    for col in range(COLS):
        for row in range(ROWS):
            pushMatrix() #store the default reference frame
            translate(CELL_WIDTH*col+0.5*CELL_WIDTH, CELL_HEIGHT*row+(0.5*(CELL_HEIGHT-LOWER_CIRCLE_MARGIN_MM*DPMM)))
            circle(0,0,PETRI_DIAMETER)
            popMatrix() #lose this shifted reference frame
    endRecord()
    
    for col in range(COLS):
        for row in range(ROWS):
            pushMatrix() #store the default reference frame
            translate(CELL_WIDTH*col+0.5*CELL_WIDTH, CELL_HEIGHT*row+(0.5*(CELL_HEIGHT-LOWER_CIRCLE_MARGIN_MM*DPMM)))

            print("placed {0} bugs in petri {1}".format(count,(col,row)))
            popMatrix() #lose this shifted reference frame
     
    for col in range(COLS):
        for row in range(ROWS):  
            pushMatrix() #store the default reference frame
            translate(CELL_WIDTH*col, CELL_HEIGHT*row)
            name_field = names.pop(0)
            popMatrix() #lose this shifted reference frame
    endRecord()
    
    

    #translate to TEXT BLOCK
    popMatrix() should go back to original(0,0)
    translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX+TEXT_BLOCK_HEIGHT_PX)
    rect(0,0,TEXT_BLOCK_WIDTH_PX, TEXT_BLOCK_HEIGHT_PX)
    
         
       
    
                
    print("Done!")
                    
def draw():
    pass

```

---

<div class="post-metadata">

### Author: ![tabreturn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tabreturn/32/3697_2.png) [@tabreturn](https://discourse.processing.org/u/tabreturn)
#### Post date: [June 26, 2020, 2:32am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/2 "2020-06-26T02:32:33Z")

</div>

I tested your code. It’s working fine for me (like, no errors). I tried this combination of constants:

```auto
BORDER_MARGIN_PX,BORDER_MARGIN_PX,COLS,ROWS,CELL_WIDTH,CELL_HEIGHT,PETRI_DIAMETER,LOWER_CIRCLE_MARGIN_MM,DPMM,BORDER_MARGIN_PX,BORDER_MARGIN_PX,TEXT_BLOCK_HEIGHT_PX,TEXT_BLOCK_WIDTH_PX,TEXT_BLOCK_HEIGHT_PX = 2,2,2,2,2,2,2,2,2,2,2,2,2,2
count, names = 2, [1,2,3,4]

```

Perhaps the problem is somewhere else in your program?

---

<div class="post-metadata">

### Author: ![slashwreck](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@slashwreck](https://discourse.processing.org/u/slashwreck)
#### Post date: [June 26, 2020, 2:44am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/3 "2020-06-26T02:44:58Z")

</div>

That’s bizarre. Could it be there is some interaction with my use of `beginRecord` and `endRecord` ??? Because even if I do multiple `pushMatrix()` operations before, it still complains with the same failure on the final `popMatrix()`

The full code below.

```auto
add_library('svg')
# xml.etree module
from xml.etree import ElementTree
import math
import utils
import life

import random as ran

DPMM = 96/25.4 # dots per mm  
PAPER_WIDTH_PX = int(210 * DPMM) #A4
PAPER_HEIGHT_PX = int(297 * DPMM) #A4

BORDER_MARGIN_PX = 15 * DPMM
TEXT_BLOCK_HEIGHT_PX = 30 * DPMM
TEXT_BLOCK_WIDTH_PX = PAPER_WIDTH_PX - 2*BORDER_MARGIN_PX
DISH_BLOCK_HEIGHT_PX = PAPER_HEIGHT_PX - 2*BORDER_MARGIN_PX - TEXT_BLOCK_HEIGHT_PX
DISH_BLOCK_WIDTH_PX = PAPER_WIDTH_PX - 2*BORDER_MARGIN_PX

ROWS=3
COLS=2

CELL_HEIGHT = DISH_BLOCK_HEIGHT_PX / ROWS
CELL_WIDTH = DISH_BLOCK_WIDTH_PX / COLS

PETRI_DIAMETER = 0.85*min(CELL_WIDTH, CELL_HEIGHT)
LOWER_CIRCLE_MARGIN_MM = 10#*DPMM

TEXT_SIZE_PX = 0.8*LOWER_CIRCLE_MARGIN_MM * DPMM

print("CELL_HEIGHT {0} CELL_WIDTH {1}".format(CELL_HEIGHT, CELL_WIDTH))

OUTPUT_FN = '.\\graphics\\combined.svg'

def settings():
    size(PAPER_WIDTH_PX, PAPER_HEIGHT_PX)

def setup():
    noLoop()
    svgs = ['.\\graphics\\99_dishes.svg',]
    
    #initial alignment for Dish Block
    translate(0,0)
    pushMatrix() #store the default reference frame       

    #even pushing multiple uncessary times results in same failure.
    #translate(0,0)
    #pushMatrix()     
 
    translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX)

    beginRecord(SVG, svgs[0])
    noFill()
    for col in range(COLS):
        for row in range(ROWS):
            pushMatrix() #store the default reference frame
            #translate(CELL_WIDTH*col, CELL_HEIGHT*row)
            #circle(0.5*CELL_WIDTH,CELL_HEIGHT-0.5*PETRI_DIAMETER-LOWER_CIRCLE_MARGIN_MM*DPMM,PETRI_DIAMETER)
            translate(CELL_WIDTH*col+0.5*CELL_WIDTH, CELL_HEIGHT*row+(0.5*(CELL_HEIGHT-LOWER_CIRCLE_MARGIN_MM*DPMM)))
            circle(0,0,PETRI_DIAMETER)
            popMatrix() #lose this shifted reference frame
    endRecord()
    
    
    #speciesFactory = life.GermSpeciesFactory(PETRI_DIAMETER)
    speciesFactory = life.BezierGermSpeciesFactory(PETRI_DIAMETER)
    
    names = []
    for col in range(COLS):
        for row in range(ROWS):
            #factory = ran.choice([life.BezierGermSpeciesFactory(PETRI_DIAMETER),life.GermSpeciesFactory(PETRI_DIAMETER)])
            factory = life.BezierGermSpeciesFactory(PETRI_DIAMETER)
            singleSpecies = factory.new_species()
            print(singleSpecies)
            names.append(singleSpecies.name)
            bugs = []
            svgs.append(".\\graphics\\{0}_cell.svg".format((col,row)))
            beginRecord(SVG, svgs[-1])
            pushMatrix() #store the default reference frame
            #xtrans, ytrans = (CELL_WIDTH*col+0.5*CELL_WIDTH, CELL_HEIGHT*row+0.5*CELL_HEIGHT)
            #print("translating to {0}, {1}".format(xtrans, ytrans))
            #translate(xtrans, ytrans)
            translate(CELL_WIDTH*col+0.5*CELL_WIDTH, CELL_HEIGHT*row+(0.5*(CELL_HEIGHT-LOWER_CIRCLE_MARGIN_MM*DPMM)))

            count = 0
            for _ in range(ran.randint(0,20)):
                #print("col {0} row {1} bug {2}".format(col, row, _))
                bugs.append(singleSpecies.germ())
                bugs[-1].plot(show_control=False)
                count+=1
            print("placed {0} bugs in petri {1}".format(count,(col,row)))
                    
            #choose specie and quantity
            # get list of n-germs, name from a new species
            popMatrix() #lose this shifted reference frame
            endRecord()
     
    FONT_SIZE=10

    svgs.append(".\\graphics\\88_text.svg")
    beginRecord(SVG, svgs[-1])   
    for col in range(COLS):
        for row in range(ROWS):  
            pushMatrix() #store the default reference frame
            translate(CELL_WIDTH*col, CELL_HEIGHT*row)
            fill(0)
            name_field = names.pop(0)
            text(name_field,
                0.5*CELL_WIDTH,
                CELL_HEIGHT-(0.5*LOWER_CIRCLE_MARGIN_MM*DPMM)-0.5*FONT_SIZE,
                CELL_WIDTH,
                LOWER_CIRCLE_MARGIN_MM*DPMM
                )        
            popMatrix() #lose this shifted reference frame
    endRecord()
    
    
    svgs.append(".\\graphics\\77_title.svg")
    beginRecord(SVG, svgs[-1])   
    #translate to TEXT BLOCK
    print("dies here...")
    popMatrix() #goes back to original(0,0) ###FAILS HERE
    translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX+TEXT_BLOCK_HEIGHT_PX)
    rect(0,0,TEXT_BLOCK_WIDTH_PX, TEXT_BLOCK_HEIGHT_PX)
    
    endRecord()
    
    
    
    
    
    
    
    # create an empty combined.svg file
    beginRecord(SVG, OUTPUT_FN); endRecord()
    ElementTree.register_namespace('', 'http://www.w3.org/2000/svg')
    tree = ElementTree.parse(OUTPUT_FN)
    combined = tree.getroot()
    
    # add the (circles/squares) svgs to the combined.svg file
    for svg in svgs:
        file = ElementTree.parse(svg).getroot()
        group = ElementTree.SubElement(combined, 'g')
        group.set('id', svg)
        group.set('inkscape:groupmode', 'layer')
        group.set('inkscape:label', svg)
        for child in file.getchildren():
            group.append(child)
    
    # save the changes to the combined.svg file
    tree.write(OUTPUT_FN)
    
    if True:    
        with open(OUTPUT_FN) as f:
            s = f.read()
        
        with open(OUTPUT_FN, "w") as f:
            old_string = "text style=\"stroke:none;\""
            new_string = "text style='stroke:none;text-anchor:middle;dominant-baseline:center'"       
            s = s.replace(old_string, new_string)
            f.write(s)
                
    print("Done!")
                    
def draw():
    pass

```

---

<div class="post-metadata">

### Author: ![tabreturn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tabreturn/32/3697_2.png) [@tabreturn](https://discourse.processing.org/u/tabreturn)
#### Post date: [June 26, 2020, 4:49am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/4 "2020-06-26T04:49:29Z")

</div>

And if you place an `endRecord()` above the problematic line?

```auto
    ...
    endRecord()
    popMatrix() #goes back to original(0,0) ###FAILS HERE
    ...

```

---

<div class="post-metadata">

### Author: ![slashwreck](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@slashwreck](https://discourse.processing.org/u/slashwreck)
#### Post date: [June 26, 2020, 6:02am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/5 "2020-06-26T06:02:16Z")

</div>

Yeah, so I moved the `popMatrix()` outside the begin/endRecord block and it works:

```auto
        popMatrix()
        svgs.append(".\\graphics\\77_title.svg")
        beginRecord(SVG, svgs[-1])   
        #translate to TEXT BLOCK
        print("dies here...")
        noFill()
        translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX+DISH_BLOCK_HEIGHT_PX)
        rect(0,0,TEXT_BLOCK_WIDTH_PX, TEXT_BLOCK_HEIGHT_PX)
        endRecord()

```

I don’t understand why this is required, as in other blocks, the `popMatrix()` occurs inside a `begin/EndRecord()` Wish there was a way to view ‘the stack’ and figure out what’s going on behind the scenes.

---

<div class="post-metadata">

### Author: ![slashwreck](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@slashwreck](https://discourse.processing.org/u/slashwreck)
#### Post date: [June 26, 2020, 7:18am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/7 "2020-06-26T07:18:46Z")

</div>

Feels like there is some weird interaction I don’t understand between `beginRecord` `endRecord` and `*matrix` functions. When I run `printMatrix` inside a record block, for example, it prints two matrices to the console.

for example:

```auto

   print("before anything")
    printMatrix()
    pushMatrix() #store the default reference frame       

    beginRecord(SVG,svgs[0])
    translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX)
    print("translated BORDER_MARGIN_PX: {0}".format(BORDER_MARGIN_PX))
    printMatrix()
    noFill()
    rect(0,0,10,10)
    endRecord()
   
    print("done")

```

yields:

> before anything  
> 1.0000 0.0000 0.0000  
> 0.0000 1.0000 0.0000
> 
> translated BORDER\_MARGIN\_PX: 56.6929133858  
> 01.0000 00.0000 56.6929  
> 00.0000 01.0000 56.6929
> 
> 01.0000 00.0000 56.6929  
> 00.0000 01.0000 56.6929
> 
> done

---

<div class="post-metadata">

### Author: ![slashwreck](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@slashwreck](https://discourse.processing.org/u/slashwreck)
#### Post date: [June 26, 2020, 7:28am UTC](https://discourse.processing.org/t/trying-to-debug-pop-pushmatrix-can-i-see-the-stack/22170/8 "2020-06-26T07:28:49Z")

</div>

Yeah, I’m suspecting that that it maintains a separate transformationMatrix for the SVG recrod I’m creating. When I’m not inside an SVG record, it strictly shows a single matrix:

```auto
   print("before anything")
    printMatrix()
    pushMatrix() #store the default reference frame       

    beginRecord(SVG,svgs[0])
    translate(BORDER_MARGIN_PX, BORDER_MARGIN_PX)
    print("translated BORDER_MARGIN_PX: {0}".format(BORDER_MARGIN_PX))
    printMatrix()
    noFill()
    rect(0,0,10,10)
    endRecord()
   
    print("done") 
   
    print("is this a single?") #yes it's a single
    printMatrix()
    print("-----")

```

```
    > 

```

> ```
> before anything
> 
> ```
> 
> 1.0000 0.0000 0.0000  
> 0.0000 1.0000 0.0000
> 
> translated BORDER\_MARGIN\_PX: 56.6929133858  
> 01.0000 00.0000 56.6929  
> 00.0000 01.0000 56.6929
> 
> 01.0000 00.0000 56.6929  
> 00.0000 01.0000 56.6929
> 
> done  
> is this a single?  
> 01.0000 00.0000 56.6929  
> 00.0000 01.0000 56.6929
> 
> \_ \_
