Link to booklet is copied to clipboard!

Saved to booklet!

Removed from booklet!

Started capturing to booklet.

Stopped capturing to booklet.

Preferring latest booklet.

No longer prefers latest booklet.

Entered edit mode.

Exited edit mode.

Here is some code, that draws two colored squares in a figure:

%matplotlib inline import numpy as np import matplotlib.pyplot as plt plt.rc('font', size=16) fig, ax = plt.subplots() ax.set_aspect('equal') ax.grid() ax.set_xlim([-1,7]) ax.set_ylim([-1,4]) ax.set_xticks(range(7)) ax.set_yticks(range(4)) ax.fill([0, 1, 1, 0], [0, 0, 1, 1], linewidth=3,facecolor='violet',edgecolor='k') ax.fill(np.array([0, 1, 1, 0]) + 1, np.array([0, 0, 1, 1]) + 1, linewidth=3,facecolor='darkviolet',edgecolor='k')

Note now in the second call of

`fill`

, the lists with
- and -coordinates are converted to NumPy arrays so that we can
do computations on them - in this case add a constant.
In the above example, there was quite a bit of repetition in the code
for the two squares. The two lists for the - and -coordinates
were repeated, and the linewidth and edgecolor specifications were
given twice. Now, Python has a number of means of reducing the amount
of code needed when
doing rather similar stuff. We have already seen a
*function*. Here is an example:

`for`

-loop doing the job, but there is another practical
way, namely a def plot_square(x,y,col): xs = np.array([0, 1, 1, 0]) ys = np.array([0, 0, 1, 1]) ax.fill(x + xs,y + ys,linewidth=3,facecolor=col,edgecolor='k')

where
We may now call the function, specifying only the position of the
square and its color - not the other details:

`def`

declares that a function is specified,
where `plot_square`

is the name of the function in this
example, and where `(x,y,col)`

specify that three arguments must be
given when calling the function. The colon, `:`

, and the
indentation are part of the syntax. Everything indented will be executed
when the function is called. The indentation must be uniform
- typically four spacings.
plot_square(0,2,'lime') fig

And we may keep going with very little code, that is easy to read:

plot_square(2,0,'yellow') plot_square(4,0,'orangered') plot_square(5,2,'chocolate') fig

When calling the

`fill`

method on the Axel object
("method" is the accurate name for a function that is addressed
via an object) a new Polygon object is created and appears in the
figure. However, the calling of `fill`

actually also
returns some information. By storing the returned info in a variable
we can inspect it. So lets start over again, but now capturing the
output from `ax.fill`

in a variable `fill_output`

:
fig, ax = plt.subplots() ax.set_aspect('equal') ax.grid() ax.set_xlim([-1,7]) ax.set_ylim([-1,4]) ax.set_xticks(range(7)) ax.set_yticks(range(4)) xs = np.array([0, 1, 1, 0]) ys = np.array([0, 0, 1, 1]) fill_output = ax.fill(xs,ys,linewidth=3, facecolor='red',edgecolor='k') fill_output

The returned information appears in the Jupyter output cell:

[<matplotlib.patches.Polygon at 0x7fa82ef5a650>]

and the plotted square in the figure:

Now, as already seen from the square parentheses and the content in between, the returned
value from

`fill`

is a list whose first (and only) element is the just-created Polygon object::
print('type(fill_output):',type(fill_output)) my_square = fill_output[0] print('type(my_square):',type(my_square)) print('my_square',my_square)

type(fill_output): <class 'list'> type(my_square): <class 'matplotlib.patches.Polygon'> my_square Polygon5((0, 0) ...)

Having called the Polygon object *after* the initial call of

`my_square`

above, we
may now modify the drawn square `fill`

. Calling the `set`

method on `my_square`

:
my_square.set(facecolor='cadetblue') fig

e.g. allows for changing the color of the square:

Since we might want to modify drawing objects after drawing them
initially, it is helpful to have our plotting function return the
drawn Polygon. Following what was done in the last section, we rewrite
the function to return the first element of the list that

`fill`

returns:
def plot_square(x,y,col): fill_output = ax.fill(x + xs, y + ys, linewidth=3, facecolor=col, edgecolor='k') # fill_output is a list # its first (and only) element is a Polygon object the_square = fill_output[0] return the_square

Now, we can name the squares as we draw them with our function:

square1 = plot_square(0,2,'lightskyblue') square2 = plot_square(4,1,'dodgerblue') fig

and we may return to them and e.g. change their color at a later stage:

print(square1) print(square2) square1.set(facecolor='darkorange') square2.set(facecolor='yellow') fig

Polygon5((0, 2) ...) Polygon5((4, 1) ...)

It is possible to change the coordinates of a drawn polygon. Firstly,
one may inspect the coordinates that the polygon has currently:

xy_vals = square1.get_xy() xy_vals

array([[0., 2.], [1., 2.], [1., 3.], [0., 3.], [0., 2.]])

The returned two-dimensional NumPy array can then be modified, here
adding two to all -coordinates and subtracting one from all -coordinates:

new_xy_vals = xy_vals + [2,-1] new_xy_vals

array([[2., 1.], [3., 1.], [3., 2.], [2., 2.], [2., 1.]])

The modified NumPy array may then be used to overwrite the coordinates
of the polygon in this way:

square1.update({'xy': new_xy_vals}) fig

where the argument supplied to the Polygon objects

`update`

method is a dictionary. The square moves accordingly:
In the above example, the
function returning the Polygon object
was deliberately written on several lines to become easily
readable. However, one may wish to write it in a more compact manner,
for instance like this:

def plot_square_more_compact(x,y,col): return ax.fill(x + xs, y + ys, linewidth=3, facecolor=col, edgecolor='k')[0] # note the [0] square3 = plot_square_more_compact(3,0,'pink') fig

Once deleted this booklet is gone forever!

Choose which booklet to go to: