How to get Coordinates of a Sphere? - python

I want to know all the coordinates of this plot:
Source: http://matplotlib.org/examples/mplot3d/surface3d_demo2.html
Source: https://stackoverflow.com/a/11156353/3755171
And plot it as a sphere of dots(Consider only one of them, I can't find that kind):
OR Even the Matrix will Do.
When I tried to plot the above mentioned ones I got:
MY CODE
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
#ax = fig.add_subplot(111, projection='3d')
ax = Axes3D(fig)
u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j]
x=np.cos(u)*np.sin(v)
y=np.sin(u)*np.sin(v)
z=np.cos(v)
#ax.plot_wireframe(x, y, z, color="r")
#ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
ax.plot(x,y,z,"o")
plt.show()

If you replace the call to plot with scatter as shown below then you will re-create a sphere composed entirely of points. See documentation here.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
#ax = fig.add_subplot(111, projection='3d')
ax = Axes3D(fig)
u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j]
x=np.cos(u)*np.sin(v)
y=np.sin(u)*np.sin(v)
z=np.cos(v)
#ax.plot_wireframe(x, y, z, color="r")
#ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
ax.scatter(x,y,z,"o")
plt.show()

Related

Matplotlib smoothing 3D surface data

I have an issue with smoothing out the mesh representation of my 3D surface with matplotlib. Below, please see my example. I am having a hard time figuring out how to make the plot look nicer/smoother if possible. Thank you for your time in advance!
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import LightSource
import numpy as np
X = [1,1,1,1,1,1,50,50,50,50,50,50]
Y = [3,5,7,8,9,10,3,5,7,8,9,10]
Z = [5.23,3.11,17.54,0.93,40.11,10.15,1.47,14.32,5.46,55.93,40.8,10.2]
x = np.reshape(X, (2, 6))
y = np.reshape(Y, (2, 6))
z = np.reshape(Z, (2, 6))
X, Y = np.meshgrid(x, y)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z)
ax.set_xlabel('Persistence Length')
ax.set_ylabel('Complexity')
ax.set_zlabel('Relative number of configurational states')
surf = ax.plot_surface(x, y, z, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
To obtain smooth line/surface you can set antialiased=True on the surface plot. Note that you were plotting two identical surface: in the following example I have eliminated the first.
To obtain a smoother mesh, you probably want to interpolate between your data points. One way to do that is to use griddata from the scipy.interpolate module.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from scipy.interpolate import griddata
X = [1,1,1,1,1,1,50,50,50,50,50,50]
Y = [3,5,7,8,9,10,3,5,7,8,9,10]
Z = [5.23,3.11,17.54,0.93,40.11,10.15,1.47,14.32,5.46,55.93,40.8,10.2]
points = np.array([X, Y]).T
# create a grid of coordinates between the minimum and
# maximum of your X and Y. 50j indicates 50 discretization
# points between the minimum and maximum.
X_grid, Y_grid = np.mgrid[1:50:50j, 3:10:50j]
# interpolate your values on the grid defined above
Z_grid = griddata(points, Z, (X_grid, Y_grid), method='cubic')
fig = plt.figure(constrained_layout=True)
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('Persistence Length')
ax.set_ylabel('Complexity')
ax.set_zlabel('Relative number of configurational states')
surf = ax.plot_surface(X_grid, Y_grid, Z_grid, cmap=cm.coolwarm,
linewidth=0, antialiased=True)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
Here is an example of antialiased=False on the left, vs antialiased=True on the right:

How to get the slice of a plot3d object?

I have some points and I plot the surface of them using the code below:
import matplotlib.pyplot as plt
from matplotlib import cm, colors
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
# Create a sphere
r = 1
pi = np.pi
cos = np.cos
sin = np.sin
phi, theta = np.mgrid[0.0:pi:20j, 0.0:2.0*pi:20j]
radis=np.random.normal(1,0.2,(20,20))
x = radis*sin(phi)*cos(theta)
y = radis*sin(phi)*sin(theta)
z = radis*cos(phi)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(
x, y, z, rstride=1, cstride=1, color='c', alpha=0.3, linewidth=0)
ax.scatter3D(x,y,z, c='r')
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
# ax.set_aspect("equal")
plt.tight_layout()
plt.show()
Then I get the 3d plot result:
The thing I want to do is that get the image of any plane, like z=0.
Is there any method or library can cover this problem?

How to plot horizontal stack of heatmaps or a stack of grid?

I want to plot a stack of heatmaps, contour, or grid computed over time. The plot should like this,
I have tried this:
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
x = np.linspace(0, 1, 100)
X, Z = np.meshgrid(x, x)
Y = np.sin(X)*np.sin(Z)
levels = np.linspace(-1, 1, 40)
ax.contourf(X, Y, Z, zdir='y')
ax.contourf(X, Y+3, Z, zdir='y')
ax.contourf(X, Y+7, Z, zdir='y')
ax.legend()
ax.view_init(15,155)
plt.show()
For one my plot looks ugly. It also does not look like what I want. I cannot make a grid there, and the 2d surfaces are tilted.
Any help is really appreciated! I am struggling with this.
Related stackoverflow:
[1] Python plot - stacked image slices
[2] Stack of 2D plot
How about making a series of 3d surface plots, with the data your wish to present in contour plotted as facecolor?
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Z = np.arange(-5, 5, 0.25)
X, Z = np.meshgrid(X, Z)
C = np.random.random(size=40*40*3).reshape((40, 40, 3))
ax.plot_surface(X, np.ones(shape=X.shape)-1, Z, facecolors=C, linewidth=0)
ax.plot_surface(X, np.ones(shape=X.shape), Z, facecolors=C, linewidth=0)
ax.plot_surface(X, np.ones(shape=X.shape)+1, Z, facecolors=C, linewidth=0)

Python : Best way to draw 3d function with random x and y

I generated a 2d array, in each row, there is a random x, random y and f(x,y).
I chose random x and y because f(x, y) is very long to compute.
I used Axes3D from mpl_toolkits.mplot3d to draw the result :
ax.scatter(tableau[:,0], tableau[:,1], zs=tableau[:,2], c='r', marker='o')
The result is not useful. Impossible to understand the shape of f
Is there a better way to draw f(x,y)?
If your goal is to see the shape of your function better you can rotate the axes with matplotlib method view_init(elev=None, azim=None); it sets the elevation and azimuth of the axes angle . For example:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Test 3D function
X, Y, Z = axes3d.get_test_data(0.1)
ax.plot_wireframe(X, Y, Z, rstride=5, cstride=5)
ax.view_init(elev, azim)
plt.draw()
With elev=30 and azim=45:
With elev=30 and azim=90:
With elev=0 and azim=90:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
elev=70
azim=30
X, Y, Z = tableau[:,0], tableau[:,1], tableau[:,2]
ax.plot_wireframe(X, Y, Z, rstride=5, cstride=5)
ax.view_init(elev, azim)
plt.draw()

Surface and 3d contour in matplotlib

I would like to plot a surface with a colormap, wireframe and contours using matplotlib. Something like this:
Notice that I am not asking about the contours that lie in the plane parallel to xy but the ones that are 3D and white in the image.
If I go the naïve way and plot all these things I cannot see the contours (see code and image below).
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 = np.sin(np.pi*X)*np.sin(np.pi*Y)
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()
If a add transparency to the surface facets then I can see the contours, but it looks really cluttered (see code and image below)
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 = np.sin(np.pi*X)*np.sin(np.pi*Y)
ax.plot_surface(X, Y, Z, cmap="autumn_r", lw=0.5, rstride=1, cstride=1, alpha=0.5)
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()
Question: Is there a way to obtain this result in matplotlib? The shading is not necessary, though.
Apparently it is a bug, if you try this
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 = np.sin(np.pi*X)*np.sin(np.pi*Y)
ax.plot_surface(X, Y, Z, cmap="autumn_r", lw=0, rstride=1, cstride=1)
ax.contour(X, Y, Z+1, 10, lw=3, colors="k", linestyles="solid")
plt.show()
And rotate around, you will see the contour lines disappearing when they shouldn't
I think you want to set the offset to the contour :
ax.contour(X, Y, Z, 10, offset=-1, lw=3, colors="k", linestyles="solid", alpha=0.5)
See this example for more:
http://matplotlib.org/examples/mplot3d/contour3d_demo3.html
And the docs here:
http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#contour-plots
offset: If specified plot a projection of the contour lines on this position in plane normal to zdir
Note, zdir = 'z' by default, but you can project in the x or y direction be setting the zdir accordingly.

Categories

Resources