import matplotlib as mpl from matplotlib import pyplot as plt from matplotlib import animation from mpl_toolkits import mplot3d from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np # patch to reduce axis padding to zero; found online from mpl_toolkits.mplot3d.axis3d import Axis if not hasattr(Axis,"_get_coord_info_old"): def _get_coord_info_new(self,renderer): mins,maxs,centers,deltas,tc,highs=self._get_coord_info_old(renderer) mins+=deltas/4 maxs-=deltas/4 return mins,maxs,centers,deltas,tc,highs Axis._get_coord_info_old=Axis._get_coord_info Axis._get_coord_info=_get_coord_info_new # plotting details fig=plt.figure() ax=plt.axes(projection='3d') ax.set_aspect(1) # aspect ratio ax.set_proj_type('ortho') plt.gca().patch.set_facecolor('#c0c0c0') fig.set_facecolor('#c0c0c0') ax.w_xaxis.set_pane_color((0,0,0,0)) ax.w_yaxis.set_pane_color((0,0,0,0)) ax.w_zaxis.set_pane_color((0,0,0,0)) font = {'size':20} plt.rc('font',**font) # set axis limits and labels and remove ticks ax.set_xlim(-1,1) ax.set_ylim(-1,1) ax.set_zlim(0,1) ax.set_xlabel('$x$') ax.set_ylabel('$y$') ax.set_zlabel('$z$') import matplotlib.ticker as ticker ax.w_xaxis.set_major_locator(ticker.FixedLocator([])) ax.w_yaxis.set_major_locator(ticker.FixedLocator([])) ax.w_zaxis.set_major_locator(ticker.FixedLocator([])) # set color ranges cmap_Blues = mpl.cm.Blues(np.linspace(0,1,20)) cmap_Blues = mpl.colors.ListedColormap(cmap_Blues[10:,:-1]) cmap_Oranges = mpl.cm.Oranges(np.linspace(0,1,20)) cmap_Oranges = mpl.colors.ListedColormap(cmap_Oranges[10:,:-1]) # make the font size of the axis labels larger for item in ([ax.title, ax.xaxis.label, ax.yaxis.label, ax.zaxis.label] + ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()): item.set_fontsize(20) # create the plotting grid and choose the contour labels xlist=np.linspace(-1,1,50) ylist=np.linspace(-1,1,50) zlist=np.linspace(0,1,20) X_surface,Y_surface=np.meshgrid(xlist,ylist) levels=np.linspace(0,1,6) # set the Gaussian parameters gc1_mag, gc1_x, gc1_y, gc1_wx, gc1_wy = 0.5, 0.2, 0, 0.42, 1.414 # set center, magnitude, and widths of Gaussian 1 gc2_mag, gc2_x, gc2_y, gc2_wx, gc2_wy = 0.7, -0.1, 0.2, 0.359, 0.424 # set center, magnitude, and widths of Gaussian 2 gc3_mag, gc3_x, gc3_y, gc3_wx, gc3_wy = 0.3, -0.6, -0.6, 1.826, 0.913 # set center, magnitude, and widths of Gaussian 3 def zfunct(x,y): def gaussian(gc_mag, gc_x, gc_y, gc_wx, gc_wy): return gc_mag*np.exp(-(((x-gc_x)/gc_wx)**2+((y-gc_y)/gc_wy)**2)) return np.sum([gaussian(gc1_mag, gc1_x, gc1_y, gc1_wx, gc1_wy), gaussian(gc2_mag, gc2_x, gc2_y, gc2_wx, gc2_wy), gaussian(gc3_mag, gc3_x, gc3_y, gc3_wx, gc3_wy)],axis=0) # print the surface contours surface=ax.plot_surface(X_surface,Y_surface, np.array(zfunct(X_surface,Y_surface)), cmap=cmap_Blues,edgecolor='none',alpha=0.3) surface_contour=ax.contour(X_surface,Y_surface,zfunct(X_surface,Y_surface), levels, cmap=cmap_Blues) # print the planar curve, a rotated parabola account_for_rot=0.1 # shifts planar curve over X_plane,Z_plane=np.meshgrid(xlist+account_for_rot,zlist) angle=np.radians(-170) X_plane_rot,Y_plane,Y_plane_rot=[],[],[] for idx,i in enumerate(X_plane): Y_plane.append((X_plane[idx]/2)**2+0.5) X_plane_rot.append(X_plane[idx]*np.cos(angle)+Y_plane[idx]*-np.sin(angle)) Y_plane_rot.append(X_plane[idx]*np.sin(angle)+Y_plane[idx]*np.cos(angle)) plane=ax.plot_surface(X_plane_rot,Y_plane_rot,Z_plane,cmap=cmap_Oranges, edgecolor='none', alpha=0.3) plane_contour=ax.contour(X_plane_rot,Y_plane_rot,Z_plane, [0.01,0.99],colors='orange') # add annotations ann1=ax.annotate('$f$',xy=(0,0),xytext=(-10,-10), fontsize=16,color='darkblue') ann2=ax.annotate('$g=g_0$',xy=(0,0),xytext=(-10,-10),fontsize=16,color='xkcd:dirty orange') # set view angles azim=-90-1e-2 elev=90-1e-2 ax.azim=azim ax.elev=elev ax.azim=-135 # for a quick standard view ax.elev=45 # set up the animation frames_full=220 frames=frames_full*(1-1/11) def animate(j): i=j-frames/10 if j