I am using imsave()
sequentially to make many PNGs that I will combine as an AVI and I would like to add moving text annotations. I use ImageJ to make AVIs or GIFs.
I don't want the axes, numbers, borders or anything, just the color image (as imsave()
provides for example) with text (and maybe arrows) inside. These will change frame by frame. Pardon the use of jet.
I could use savefig()
with ticks off and then do cropping as post processing, but is there a more convenient, direct, or "matplotlibithic" way to do this that wouldn't be so hard on my hard drive? (final thing will be pretty big).
A code snippet, added by request:
import numpy as np
import matplotlib.pyplot as plt
nx, ny = 101, 101
phi = np.zeros((ny, nx), dtype = 'float')
do_me = np.ones_like(phi, dtype='bool')
x0, y0, r0 = 40, 65, 12
x = np.arange(nx, dtype = 'float')[None,:]
y = np.arange(ny, dtype = 'float')[:,None]
rsq = (x-x0)**2 + (y-y0)**2
circle = rsq <= r0**2
phi[circle] = 1.0
do_me[circle] = False
do_me[0,:], do_me[-1,:], do_me[:,0], do_me[:,-1] = False, False, False, False
n, nper = 100, 100
phi_hold = np.zeros((n+1, ny, nx))
phi_hold[0] = phi
for i in range(n):
for j in range(nper):
phi2 = 0.25*(np.roll(phi, 1, axis=0) +
np.roll(phi, -1, axis=0) +
np.roll(phi, 1, axis=1) +
np.roll(phi, -1, axis=1) )
phi[do_me] = phi2[do_me]
phi_hold[i+1] = phi
change = phi_hold[1:] - phi_hold[:-1]
places = [(32, 20), (54,25), (11,32), (3, 12)]
plt.figure()
plt.imshow(change[50])
for (x, y) in places:
plt.text(x, y, "WOW", fontsize=16)
plt.text(5, 95, "Don't use Jet!", color="white", fontsize=20)
plt.show()
Method 1
Using an excellent answer to another question as a reference, I came up with the following simplified variant which seems to work nicely - just make sure the
figsize
(which is given in inches) aspect ratio matches the size ratio of the plot data:Note that I am using
imshow
with atest_image
, which might behave differently from other plotting functions... please let me know in a comment in case you'd like to do something else.Also note that the image will be (re-) sampled, so the
figsize
will influence the resolution of the written image.As pointed out in the comments, the
figsize
setting doesn't match the size of the output image (or the size on screen, for that matter). To overcome this, use...Method 2
Reading the FAQ entry Move the edge of an axes to make room for tick labels, I found a way to make the
figsize
parameter set the output image size directly, by moving the axes' ticks out of the visible area:Note that
savefig
has a default DPI setting (100 in my case) which - in combination withfigsize
- determines the number of pixels in x and y directions of the saved image. You can override this with thedpi
keyword argument tosavefig
.If you want to display the image on screen rather than saving it (by using
plt.show()
instead of theplt.savefig
line in the code above), the size of the figure is dependent on (apart from the already familiarfigsize
parameter) the figure's DPI setting, which also has a default (80 on my system). This value can be overridden by passing thedpi
keyword argument to theplt.figure()
call.