Figures, Subplots, Axes and Ticks
Figures
A figure is the windows in the GUI that has "Figure #" as title. Figures are numbered starting from 1 as opposed to the normal Python way starting from 0. This is clearly MATLAB-style. There are several parameters that determine what the figure looks like:
Argument | Default | Description |
---|---|---|
num | 1 | number of figure |
figsize | figure.figsize | figure size in in inches (width, height) |
dpi | figure.dpi | resolution in dots per inch |
facecolor | figure.facecolor | color of the drawing background |
edgecolor | figure.edgecolor | color of edge around the drawing background |
frameon | True | draw figure frame or not |
The defaults can be specified in the resource file and will be used most of the time. Only the number of the figure is frequently changed.
When you work with the GUI you can close a figure by clicking on the x in the upper right corner. But you can close a figure programmatically by calling close. Depending on the argument it closes (1) the current figure (no argument), (2) a specific figure (figure number or figure instance as argument), or (3) all figures (all as argument).
As with other objects, you can set figure properties with the set_something methods.
Subplot
Axis
Ticks
Tick Locators
There are several locators for different kind of requirements:
Class | Description |
---|---|
NullLocator | No ticks. ![]() |
IndexLocator | Place a tick on every multiple of some base number of points plotted. ![]() |
FixedLocator | Tick locations are fixed. ![]() |
LinearLocator | Determine the tick locations. ![]() |
MultipleLocator | Set a tick on every integer that is multiple of some base. ![]() |
AutoLocator | Select no more than n intervals at nice locations. ![]() |
LogLocator | Determine the tick locations for log axes. ![]() |
All of these locators derive from the base class matplotlib.ticker.Locator. You can make your own locator deriving from it. Handling dates as ticks can be especially tricky. Therefore, matplotlib provides special locators in matplotlib.dates.
Animation
For quite a long time, animation in matplotlib was not an easy task and was done mainly through clever hacks. However, things have started to change since version 1.1 and the introduction of tools for creating animation very intuitively, with the possibility to save them in all kind of formats (but don't expect to be able to run very complex animation at 60 fps though).
Documentation
- See Animation
The most easy way to make an animation in matplotlib is to declare a FuncAnimation object that specifies to matplotlib what is the figure to update, what is the update function and what is the delay between frames.
Drip drop
A very simple rain effect can be obtained by having small growing rings randomly positioned over a figure. Of course, they won't grow forever since the wave is supposed to damp with time. To simulate that, we can use a more and more transparent color as the ring is growing, up to the point where it is no more visible. At this point, we remove the ring and create a new one.
First step is to create a blank figure:
fig = plt.figure(figsize=(6,6),facecolor='white')
ax = fig.add_axes([0,0,1,1], frameon=False, aspect=1)
plt.show()
Next, we need to create several rings. For this, we can use the scatter plot object that is generally used to visualize points cloud, but we can also use it to draw rings by specifying we don't have a facecolor. We have also to take care of initial size and color for each ring such that we have all size between a minimum and a maximum size and also to make sure the largest ring is almost transparent.
#rain position
P = np.random.uniform(0,1,(n,2))
#ring color
C = np.ones((n,4)) * (0,0,0,1)
C[:,3] = np.linspace(0,1,n)
S = np.linspace(size_min, size_max, n)
scat = ax.scatter(P[:,0],P[:,1],s=S, lw=0.5, edgecolors=C, facecolors='None')#x坐标 y坐标 大小 粗细 边缘线颜色 内部颜色
ax.set_xlim(0,1), ax.set_xticks([])
ax.set_ylim(0,1), ax.set_yticks([])
Now, we need to write the update function for our animation. We know that at each time step each ring should grow be more transparent while largest ring should be totally transparent and thus removed. Of course, we won't actually remove the largest ring but re-use it to set a new ring at a new random position, with nominal size and color. Hence, we keep the number of ring constant.
def update(frame):
global P, C, S
# Every ring is made more transparent 颜色更新
C[:,3] = np.maximum(0, C[:,3] - 1.0/n)
# Each ring is made larger 大小更新
S += (size_max - size_min) / n
# Reset ring specific ring (relative to frame number) 消失后重新复位
i = frame % 50
P[i] = np.random.uniform(0,1,2)
S[i] = size_min
C[i,3] = 1
# Update scatter object 更新点的属性
scat.set_edgecolors(C)
scat.set_sizes(S)
scat.set_offsets(P)
return scat,
animation = ani.FuncAnimation(fig, update, interval=10)#interval代表更新间隔