The following python code was in a reader from my university for a python course. It should plot a 3D figure but when I try to run the program it doesn't show anything.
from numpy import exp,arange,meshgrid
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import axes3d, Axes3D
def z_func(x,y):
return (1-(x**2+y**3))*exp(-(x**2+y**2)/2)
x = arange(-3.0,3.0,0.1)
y = arange(-3.0,3.0,0.1)
X,Y = meshgrid(x,y)
Z = z_func(X,Y)
fig = plt.figure()
ax = Axes3D(fig)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.RdBu,
linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show
It doesn't give an error or anything.
plt.show is a function. You need to call it: plt.show().
Related
I would like to create a smooth plot in Python. Generally, you can make a plot that looks like the one below:
Source
While this is a nice image, it looks as though it's made out of a mesh of polygons, making it look "coarse." In my own plots I have tried increasing the resolution of my function to no avail. I am trying to achieve the following "smooth" look:
Source
How do I achieve this?
Maybe you were missing rcount and ccount?
# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused import
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
# Make data.
X = np.arange(-5, 5, 0.05)
Y = np.arange(-5, 5, 0.05)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
linewidth=0, antialiased=False, rcount=200, ccount=200)
# Customize the z axis.
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
I have been trying to get the "example" picture (generated with a 3D graphic calc) using Python for a few days now, but keep running into troubles getting the segments of the plot other than the peak in the middle to show up to scale.
I am using this code:
import numpy as np
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
X, Y = np.mgrid[-1:1:30j, -1:1:30j]
Z = (2*X*Y) + (1/np.sqrt(X**2+Y**2))
ax.plot_surface(X, Y, Z, cmap="autumn_r", lw=0.5, rstride=1, cstride=1)
ax.contour(X, Y, Z, 10, lw=3, cmap="autumn_r", linestyles="solid", offset=-1)
ax.contour(X, Y, Z, 10, lw=3, colors="k", linestyles="solid")
plt.show()
Which produces this graph.
It is close, but it should look more like this one. When I lower the 30j in attempts to bring it down and hope the flares on the sides are more pronounced, it gets rid of the entire peak. I am trying to get to this.
What if you try the following line?
X, Y = np.mgrid[-7:7:100j, -7:7:100j]
I have this following code which attempts to plot a function +/- f which defines the graphene dispersion in the momentum space.
# 3D Plot of graphene dispersion
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
def sqrt(x):
return np.sqrt(x)
def cos(x):
return np.cos(x)
# Constants
a = 1.0
d = a*np.sqrt(3)
t = 2.7
t2 = 0.5
print "The display is not up to the mark! Modification needed.\n"
fig = plt.figure()
ax = fig.gca(projection='3d')
x = np.arange(-2.0*np.pi, 2.0*np.pi, 0.1)
y = np.arange(-2.0*np.pi, 2.0*np.pi, 0.1)
x, y = np.meshgrid(x, y)
f=t*sqrt(3.0+2.0*cos(a*x)+4.0*cos(a/2.0*x)*cos(d/2.0*y))
surf = ax.plot_surface(x, y, f, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False)
f=-f
surf = ax.plot_surface(x, y, f, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False)
ax.set_zlim3d(-3.0, 3.0)
fig.colorbar(surf, shrink=1.0, aspect=5)
plt.show()
which gives me a plot that overflows the z-axis boundary :
However, keeping the same function definition and using gnuplot or Mathematica I was able to produce this
and this
Can any of the last two be reproduced by using python with matplotlib?
I'm not quite sure what you want, since you explicitly set the z-limits inside the range of the data (ax.set_zlim3d(-3.0, 3.0)), but I get a similar plot simply by commenting out this line (and picking a nicer colormap):
# 3D Plot of graphene dispersion
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
sqrt = np.sqrt
cos = np.cos
# Constants
a = 1.0
d = a*np.sqrt(3)
t = 2.7
t2 = 0.5
fig = plt.figure()
ax = fig.gca(projection='3d')
x = np.arange(-2.0*np.pi, 2.0*np.pi, 0.1)
y = np.arange(-2.0*np.pi, 2.0*np.pi, 0.1)
x, y = np.meshgrid(x, y)
f=t*sqrt(3.0+2.0*cos(a*x)+4.0*cos(a/2.0*x)*cos(d/2.0*y))
surf = ax.plot_surface(x, y, f, rstride=1, cstride=1, cmap=plt.get_cmap('PuOr'),
linewidth=0, antialiased=False)
f=-f
surf = ax.plot_surface(x, y, f, rstride=1, cstride=1, cmap=plt.get_cmap('PuOr'),
linewidth=0, antialiased=False)
#ax.set_zlim3d(-3.0, 3.0)
fig.colorbar(surf, shrink=1.0, aspect=5)
plt.show()
(Note also that you don't need to define a wrapper function to create an alias to np.sqrt, etc. Functions are first class objects in Python and you can simply assign a name: sqrt = np.sqrt.)
Is it possible to disable the perspective when plotting in mplot3d, i.e. to use the orthogonal projection?
This is now official included since matplot version 2.2.2 Whats new | github
So for plotting a perspective orthogonal plot you have to add proj_type = 'ortho' then you should have something like that:
fig.add_subplot(121, projection='3d', proj_type = 'ortho')
Example Picture
]2
Example is taken from the official example script and edited
'''
======================
3D surface (color map)
======================
Demonstrates plotting a 3D surface colored with the coolwarm color map.
The surface is made opaque by using antialiased=False.
Also demonstrates using the LinearLocator and custom formatting for the
z axis tick labels.
'''
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
# Make data.
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# Plot the surface.
fig = plt.figure(figsize=(16,4))
ax.view_init(40, 60)
ax = fig.add_subplot(121, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
ax = fig.add_subplot(122, projection='3d', proj_type = 'ortho')
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.viridis, linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
plt.show()
NOTE: This has been updated see this answer instead.
Sort of, you can run this snippet of code before you plot:
import numpy
from mpl_toolkits.mplot3d import proj3d
def orthogonal_proj(zfront, zback):
a = (zfront+zback)/(zfront-zback)
b = -2*(zfront*zback)/(zfront-zback)
return numpy.array([[1,0,0,0],
[0,1,0,0],
[0,0,a,b],
[0,0,0,zback]])
proj3d.persp_transformation = orthogonal_proj
It is currently an open issue found here.
I'm new to python and after installing it I've accomplished to plot my 3d data using matplotlib. Sadly the only thing I don't know how to get done is the color part. My image just shows the surface but doesn't use the color bar at all. Here is my code.
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
from matplotlib.mlab import griddata
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
data = np.genfromtxt('Uizq.txt')
x = data[:,0]
y = data[:,1]
z = data[:,2]
xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('U')
X, Y = np.meshgrid(xi, yi)
Z = griddata(x, y, z, xi, yi)
ax.set_zlim3d(np.min(Z), np.max(Z))
surf = ax.plot_surface(X, Y, Z, rstride=2, cstride=2, cmap=cm.jet,
linewidth=0.5, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
you can obviously see that it is all blue, and I want to relate the color with "U" using the full cm.jet spectrum. This might be a very noob question, so sorry if you rolled your eyes.
Add the line
surf.set_clim([np.min(Z),np.max(Z)])
before you add the color bar.
It seems that the 3D plotting does not take into account the masking, so you are including NaN in the data, which confuses the automatic color limits.