# Square spiral with matplotlib (1)

Today, at work, a friend asked me to make a simple program to draw “square spiral based on an input number”. You can see the result below:

It’s implemented in python using `matplotlib`

to pot the square spiral. First we look for each edge to be drawn with `calc_spiral`

:

```
def calc_spiral( p_num_edges ):
"""Function to calculate each edge to draw."""
values = range( p_num_edges, -1, -1 )
state = True # if true x-axis if false y-axis
direction = True # if true + if false -
c = 0 # counter used to know when direction should change
lx = 0 # last x-axis value
ly = 0 # last y-axis value
# Each item on the list ( segments ) contains:
# ( Axis, Origin point in axis, end point in axis,
# Value of opposite axis, Drawing direction )
segments = [ ]
for i in range( len( values ) ):
# change direction each two iterations
if c % 2 == 0: direction = not direction
if state: # if x-axis
# added or subtracted according to the direction
if not direction:
nlx = lx + values[ i ]
else:
nlx = lx - values[ i ]
v = ( "x", lx, nlx, ly, direction )
lx = nlx
else: # if y-axis
# added or subtracted according to the direction
if not direction:
nly = ly + values[ i ]
else:
nly = ly - values[ i ]
v = ( "y", ly, nly, lx, direction )
ly = nly
segments.append( v )
# change axis each iteration
state = not state
c += 1
return segments
```

Calling this function we get a list of edges which look like:

```
[ ('x', 0, 4, 0, False), ('y', 0, 3, 4, False),
('x', 4, 2, 3, True), ('y', 3, 2, 2, True),
('x', 2, 2, 2, False) ]
```

Each item represents an edge of the square spiral: axis, origin point, end point, actual opposite axis value, direction (on direction `True`

means positive increment, `False`

negative).

(Sure it can be made more clean and optimal).

Gotten edges to draw we call `draw_spiral`

to clear our plot and draw the spiral:

```
def draw_spiral( self, p_segments, p_num_edges ):
"""Function used to draw segments on chart."""
# Clear axes from previous drawing
self.__axes.cla()
# Draw each segment taking care about it's axis and direction
for item in p_segments:
if item[ 0 ] == "x":
if not item[ 4 ]:
xv = range( item[ 1 ], item[ 2 ] + 1, 1 )
else:
xv = range( item[ 1 ], item[ 2 ] - 1, -1 )
yv = map( lambda _ : item[ 3 ], xv )
elif item[ 0 ] == "y":
if not item[ 4 ]:
yv = range( item[ 1 ], item[ 2 ] + 1, 1 )
else:
yv = range( item[ 1 ], item[ 2 ] - 1, -1 )
xv = map( lambda _ : item[ 3 ], yv )
self.__axes.plot( xv, yv )
# Set axis limits and draw
m = float( p_num_edges ) + 1
self.__axes.axes.set_xlim( [ -1.0, m ] )
self.__axes.axes.set_ylim( [ -1.0, m ] )
self.__fig.canvas.draw()
```

Note that in this function the figure, canvas and axis are not initialized. That’s because they’re initialized on creating the main container widget.

The complete source file is here.