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)
Related
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()
What is wrong for this code for hiding right and top axes, please?
import matplotlib.pyplot as plt
fig, ax = plt.subplots(sharex=True, sharey=True, figsize=(10,3))
fig1 = plt.subplot(121)
fig2 = plt.subplot(122)
# Set width of axes
for figures in [fig1, fig2]:
# Removing axis
for side in ['right','top']:
ax.spines[side].set_visible(False)
plt.show()
This works for non-multiple plot:
for side in ['right','top']:
ax.spines[side].set_visible(False)
EDITED CODE:
import matplotlib.pyplot as plt
import seaborn as sns
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10,3))
fig1 = plt.subplot(121)
ax1.set_xlabel(r'$k$')
ax1.set_ylabel(r'$\omega$', rotation='horizontal')
fig2 = plt.subplot(122)
sns.despine()
plt.show()
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?
I am plotting a function on the surface of a sphere. To test my code, I simply plot the spherical coordinate phi divided by pi. I get
Unexpectedly, half of the sphere is of the same color, and the colors on the other half aren't correct (at phi=pi, i should get 1, not 2). If I divide the data array by 2, the problem disappears. Can someone explain to me what is happening?
Here is the code I use:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
# prepare the sphere surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
phi = np.linspace(0,2*np.pi, 50)
theta = np.linspace(0, np.pi, 25)
x=np.outer(np.cos(phi), np.sin(theta))
y=np.outer(np.sin(phi), np.sin(theta))
z=np.outer(np.ones(np.size(phi)), np.cos(theta))
# prepare function to plot
PHI=np.outer(phi,np.ones(np.size(theta)))
THETA=np.outer(np.ones(np.size(phi)),theta)
data = PHI/np.pi
# plot
surface=ax.plot_surface(x, y, z, cstride=1, rstride=1,
facecolors=cm.jet(data),cmap=plt.get_cmap('jet'))
# add colorbar
m = cm.ScalarMappable(cmap=surface.cmap,norm=surface.norm)
m.set_array(data)
plt.colorbar(m)
plt.show()
There is a little bit of chaos in the code.
When specifying facecolors, there is no reason to supply a colormap, because the facecolors do not need to be retrieved from a colormap.
Colormaps range from 0 to 1. Your data ranges from 0 to 2. Hence half of the facecolors are just the same. So you first need to normalize the data to the (0,1)-range, e.g. using a Normalize instance, then you can apply the colormap.
norm = plt.Normalize(vmin=data.min(), vmax=data.max())
surface=ax.plot_surface(x, y, z, cstride=1, rstride=1,
facecolors=cm.jet(norm(data)))
For the colorbar you should then use the same colormap and the same normalization as for the plot itself.
m = cm.ScalarMappable(cmap=cm.jet,norm=norm)
m.set_array(data)
Complete code:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
# prepare the sphere surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
phi = np.linspace(0,2*np.pi, 50)
theta = np.linspace(0, np.pi, 25)
x=np.outer(np.cos(phi), np.sin(theta))
y=np.outer(np.sin(phi), np.sin(theta))
z=np.outer(np.ones(np.size(phi)), np.cos(theta))
# prepare function to plot
PHI=np.outer(phi,np.ones(np.size(theta)))
THETA=np.outer(np.ones(np.size(phi)),theta)
data = PHI/np.pi
# plot
norm = plt.Normalize(vmin=data.min(), vmax=data.max())
surface=ax.plot_surface(x, y, z, cstride=1, rstride=1,
facecolors=cm.jet(norm(data)))
# add colorbar
m = cm.ScalarMappable(cmap=cm.jet,norm=norm)
m.set_array(data)
plt.colorbar(m)
plt.show()
I have code like:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(xs, ys, zs, c='r', marker='o',label='A')
ax.scatter(x, y, z, c='b', marker='^',label='B')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.tick_params(axis='both', which='major', labelsize=6)
ax.tick_params(axis='both', which='minor', labelsize=6)
plt.savefig(outfile)
The tickparams which works in the 2D version is not working.
How do I do this? The documentation is very hard to read on this.
Note, this is the font size of the titles of the axes, not the tick labels.
The code from the question runs fine.
ax.tick_params(..., labelsize=6)
can be used to change the fontsize of the labels.
The complete example
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x,y,z = zip(*np.random.rand(10,3))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c='b', marker='^',label='B')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.tick_params(axis='both', which='major', labelsize=6)
ax.tick_params(axis='both', which='minor', labelsize=6)
plt.show()
produces this plot: