Hello,
I want like to make an animation by reading the data for a 3d surface, plotting it and rotating the 3d plot as a function of time. I want to use proplot for the 3d plot. Here is a minimal working example plot.py
:
import matplotlib.ticker as ticker
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#with proplot
import proplot as pplt
colormap = plt.cm.get_cmap('jet') # 'plasma' or 'viridis'
#define the folder where to read the data
L = 1
number_of_frames = 32
#number of bins in the x, y axis for the z surface
N_bins = [100,100]
z_min = -1
z_max = 1
altitude = 30
azimuth_min = -45.0
azimuth_max = azimuth_min +90
#the data of the height z will be stored in data_z
X, Y = np.meshgrid( np.linspace( 0, L, N_bins[0] ), np.linspace( 0, L, N_bins[1] ), indexing='ij' )
grid_z = np.cos(2*np.pi*(X-Y))
#OPTION A: WITHOUT PROPLOT
fig = plt.figure(figsize = (4,4))
#OPTION B: WITH PROPLOT
# fig = pplt.figure(figsize = (4,4), left=2, bottom=-2, right=0, top=-6, wspace=None, hspace=-13)
# ==============
# Plot
# ==============
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.set_box_aspect([L, L, z_max-z_min])
ax.set(xlim=[0, L], ylim=[0, L], zlim=[z_min,z_max])
ax.xaxis.set_major_locator(ticker.MultipleLocator(base=1)) # x-axis ticks at multiples of 1.0
ax.yaxis.set_major_locator(ticker.MultipleLocator(base=1)) # y-axis ticks at multiples of 1.0
ax.zaxis.set_major_locator(ticker.MultipleLocator(base=1)) # y-axis ticks at multiples of 0.01
ax.grid(False)
ax.xaxis.pane.fill = False # Left pane
ax.yaxis.pane.fill = False # Right pane
ax.zaxis.pane.fill = False # Bottom pane
ax.view_init(elev=altitude, azim=-133)
plot = [ax.plot_surface(X, Y, grid_z, cmap = colormap, edgecolor='black', lw=0.5, rstride=3, cstride=4, alpha=.75, zorder=2)]
Writer = animation.writers['ffmpeg']
writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=(int)(1e4))
def update_animation(n):
plot[0].remove()
plt.clf()
# ==============
# Plot
# ==============
ax = fig.add_subplot(1, 1, 1, projection='3d' )
ax.view_init( elev=altitude, azim=azimuth_min + (azimuth_max - azimuth_min) * n/(number_of_frames-1))
ax.set_box_aspect( [L, L, z_max - z_min] )
ax.set( xlim=[0, L], ylim=[0, L], zlim=[z_min, z_max] )
ax.xaxis.set_major_locator( ticker.MultipleLocator( base=1 ) ) # x-axis ticks at multiples of 1.0
ax.yaxis.set_major_locator( ticker.MultipleLocator( base=1 ) ) # y-axis ticks at multiples of 1.0
ax.zaxis.set_major_locator( ticker.MultipleLocator( base=1 ) ) # y-axis ticks at multiples of 0.01
ax.grid( False )
ax.xaxis.pane.fill = False # Left pane
ax.yaxis.pane.fill = False # Right pane
ax.zaxis.pane.fill = False # Bottom pane
plot[0] = ax.plot_surface( X, Y, grid_z, cmap=colormap, edgecolor='black', lw=0.5, rstride=3, cstride=4, alpha=.75, zorder=2 )
ani = animation.FuncAnimation(
fig=fig,
func=update_animation,
frames=number_of_frames,
#interval between subsequent frames in milliseconds
interval=30)
ani.save('animation.mp4', writer=writer)
plt.savefig("figure1.pdf")
plt.show()
If I run with OPTION A (without using proplot, using matplotlib only), it runs and I get an .mp4 movie file. If I run with option B (with proplot) I get
plot.py
Traceback (most recent call last):
File "/Users/jean/Documents/learn-matplotlib/plot.py", line 81, in <module>
ani.save('animation.mp4', writer=writer)
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/matplotlib/animation.py", line 1089, in save
anim._draw_next_frame(d, blit=False)
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/matplotlib/animation.py", line 1125, in _draw_next_frame
self._post_draw(framedata, blit)
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/matplotlib/animation.py", line 1150, in _post_draw
self._fig.canvas.draw_idle()
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/matplotlib/backend_bases.py", line 2060, in draw_idle
self.draw(*args, **kwargs)
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/proplot/figure.py", line 468, in _canvas_preprocess
fig.auto_layout()
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/proplot/figure.py", line 1432, in auto_layout
_align_content()
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/proplot/figure.py", line 1422, in _align_content
self._align_super_title(renderer)
File "/Users/jean/Library/Python/3.9/lib/python/site-packages/proplot/figure.py", line 1006, in _align_super_title
if not self._suptitle.get_text():
AttributeError: 'NoneType' object has no attribute 'get_text'
Process finished with exit code 1
Do you have any idea of why this is not working ?
Thank you !
2 posts - 2 participants