Record interactive plot - matplotlib

The following code works fine to save an animation to file:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, bitrate=1800)
fig, ax = plt.subplots()
ims = []
x = np.linspace(0, np.pi,200)
for theta in np.linspace(0, np.pi, 50):
plot = ax.plot(x, np.sin(x + theta))
ims.append(plot)
im_ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True)
im_ani.save('im.mp4', writer=writer)
Now, I would like to view the animation interactively as the plots are generated, while still saving it to file. I therefore tried the following code:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, bitrate=1800)
plt.ion()
fig, ax = plt.subplots()
ims = []
x = np.linspace(0, np.pi, 200)
for theta in np.linspace(0, np.pi, 50):
ax.clear()
plot = ax.plot(x, np.sin(x + theta))
ims.append(plot)
plt.draw()
plt.pause(0.01)
im_ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True)
im_ani.save('im.mp4', writer=writer)
which lets me view the animation interactively, but the resulting video file contains only blank frames.
Is is possible to view an animation interactively and save it to file at the same time? What is the issue with my code?

Related

Why the ax.plot can not show in terminal in Windows by using matplotlib

You can see I am using ax.plot but nothing happened.
Just call plt.show() when you've run all of your graph creation code:
import numpy as np
import matplotlib.pyplot as plt
x= np.arange(-10, 10, 0.1)
fig, ax = plt.subplots()
ax.plot(x, np.cos(x))
plt.show()

Interactive matplotlib : generate and display a new image each time slider bar is moved

So, I created an ML model that takes 4 variables as inputs, that range from -1 to 1 (e.g.variables= [0.5, 0.4, -0.3, 0.9 ].
Each combination of these variables generates a different image, which I can then plot.
gen_imgs = gen_mdl.predict([variables])
# Rescale images 0 - 1
gen_imgs = 0.5 * gen_imgs + 0.5
image=255-(gen_imgs[0,:,:,0]*255)
plt.figure(figsize=(3,4))
plt.imshow(image1, cmap='gray')
plt.axis('off')
plt.show()
I've tried editing the following code to get the results I'm looking for but keep hitting errors.
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, np.sin(x))
def update(w = 1.0):
line.set_ydata(np.sin(w * x))
fig.canvas.draw()
interact(update)
UPDATE: I figured it out. Only thing I can't seem to figure out is how to limit the latent variable slider between ranges -1 to 1. This is my code:
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(4,2))
ax = fig.add_subplot(1, 1, 1)
line = ax.imshow(image1, cmap='gray')
plt.axis('off')
def update(lv_1 = 1.0):
noise[0][0]=lv_1
gen_imgs = gen_mdl.predict([noise,vfs])
gen_imgs = 0.5 * gen_imgs + 0.5
updated_image=255-(gen_imgs[0,:,:,0]*255)
line.set_data(updated_image)
fig.canvas.draw()
interact(update)

save matplotlib animation in lossless quality format

I would like to know if it possible to save matplotlib animation with lossless quality (or even vectorial format)
I have the following animation from matplotlib examples
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro')
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True)
plt.show()
I found this post from 2013 Can matplotlib animation output vector sequence? and at the time it was not possible.
Has anything changed and is it now possible to output the data into vector-like format?

matplotlib - mask portion of standalone colorbar

Below is the code to build a standalone continuous colorbar. I would like to mask, with black, all values between -3 and 3.
import matplotlib.pyplot as plt
import matplotlib as mpl
fig, ax = plt.subplots(figsize=(8, .25))
cmap = mpl.cm.twilight
norm = mpl.colors.Normalize(vmin=-9.6, vmax=9.6)
cbar = mpl.colorbar.ColorbarBase(ax, cmap=cmap, norm=norm, orientation='horizontal', ticks=[-3,3])
The function colors.ListedColormap creates a new colormap from a list of colors. The following code retrieves these colors from an existing map and makes the desired modifications:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
cmap = mpl.cm.get_cmap('twilight', 256)
norm = mpl.colors.Normalize(vmin=-9.6, vmax=9.6)
maskedcolors = cmap(np.linspace(0, 1, 256))
black = np.array([0, 0, 0, 1])
maskedcolors[int(round(norm(-3) * 256)) : int(round(norm(3) * 256)) + 1] = black
maskedcmp = mpl.colors.ListedColormap(maskedcolors)
fig, ax = plt.subplots(figsize=(8, .5))
cbar = mpl.colorbar.ColorbarBase(ax, cmap=maskedcmp, norm=norm, orientation='horizontal', ticks=[-3, 3])
fig.subplots_adjust(bottom=0.5)
plt.show()

Set zlim in matplotlib scatter3d

I have three lists xs, ys, zs of data points in Python and I am trying to create a 3d plot with matplotlib using the scatter3d method.
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
plt.xlim(290)
plt.ylim(301)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.scatter(xs, ys, zs)
plt.savefig('dateiname.png')
plt.close()
The plt.xlim() and plt.ylim() work fine, but I don't find a function to set the borders in z-direction. How can I do so?
Simply use the set_zlim function of the axes object (like you already did with set_zlabel, which also isn't available as plt.zlabel):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
xs = np.random.random(10)
ys = np.random.random(10)
zs = np.random.random(10)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.scatter(xs, ys, zs)
ax.set_zlim(-10,10)