For example I have 2 arrays that are x, y co-ordinates and a square grid that corresponds to each point.
x = np.linspace(0,10,50)
y = np.linspace(-5,12,50)
square = np.empty((50,50))
I'm trying to plot out a square surface that is cmaped by the square values. I did get it to work with surface plotting but the issue is the surface has an irregular shape and I can't plot some scatter points over it, without visibility issues.
I'm wondering if there's a way to get it to work as a 2d plot rather than 3d as the Z cordinate can just be replaced by a cmap and make sense. Any suggestions?
So I did find a solution:
x_mesh, y_mesh = np.meshgrid(x,y)
fig = plt.figure(dpi = 200)
plt.scatter(x_mesh,y_mesh, c = square, cmap = 'viridis')
plt.show
With enough points it gets a good surface.
I want to plot a plane in the z-x plane, but I am having problems.
I am able to successfully plot the plane into the z-y plane with the following code:
import plotly.graph_objects as go
import numpy as np
x1 = np.zeros(100)
y1 = np.linspace(-5, 5, 100)
z1 = np.linspace(-2.5, 2.5, 50)
rc = np.random.rand(100,50) # random surface colors
plane = go.Surface(x=x1, y=y1, z=np.array([z1] * len(x1)), surfacecolor=rc)
figure = go.Figure()
figure.add_traces([plane])
figure.show()
This gives the following figure:
To plot the same in the z-x plane, this should be achievable (from my understanding) by simply swapping the x and y parameters of the surface plot:
plane = go.Surface(x=y1, y=x1, z=np.array([z1] * len(x1)), surfacecolor=rc)
However, now the surface plot never shows up in the figure.
There is no error message or warning and looking at the data representation, all the data fields seem to be set the way they should.
So what am I missing?
Thanks for your feedback
I was having the exact same problem and google sent me here. Searching for a solution, I came across this answer: https://stackoverflow.com/a/62504443
According to the answer, you have to transpose the array of the z argument.
plane = go.Surface(x=y1, y=x1, z=np.array([z1] * len(x1)).T, surfacecolor=rc)
For the surface coloring you would have change to
rc = np.random.rand(100,100)
I am trying to plot peaks (3D topographical peaks) on ginput() points specified by a user. These peaks have to be in the form of a 3D surface plot as shown in the example image on this link 3D surface plot peaks .So far I have managed to acquire the points from the ginput() function and separated them into two different arrays one with x coordinates another with y coordinates. How do I go about plotting these peaks on these points using the cosine wave?
I am still new to python so I have written a few lines of pseudo code of what I am trying to achieve in order to try and add more clarity to my question.
import sys, numpy as np, matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
pts = []
fig = plt.figure()
ax = fig.gca(projection='3d')
Npeaks = input(' Enter your number of peaks here..')
pts = plt.ginput(Npeaks)
x=map(lambda x: x[0],pts) # creating an array with x coordinates
y=map(lambda x: x[1],pts) # creating an array with y coordinates
Pseudo code of the code I am trying to achieve
if number_of_peaks > 0 :
ax.plot_surface( plot a peak at those points )
else:
sys.exit()
ax.set_xlabel('X')
ax.set_xlim(value , value )
ax.set_ylabel('Y')
ax.set_ylim( value , value )
ax.set_zlabel('Z')
ax.set_zlim( value , value )
plt.show()
I have built some fairly simple logarithmic matplotlib scatter plots. I am happy with the results thus far, but I need to change the color of each grid area.
Current Plot:
I would like to understand how I could do the following:
I appreciate any help. Thanks.
Plot a small image underneath the scatter plot, with an integer indicating the tile color. You can then use pcolor to plot the image, with edgecolors to define the borders. The code below does this, with cell color defined as the maximum of cell index i, j, which happens to match your grid.
import numpy as np
import matplotlib.pyplot as plt
# define grid
nx, ny = 6, 5
x, y = np.arange(nx), np.arange(ny)
xx, yy = np.meshgrid(x, y)
z = np.maximum(xx, yy)
# create random points
npoints = 30
data_x = 10**(np.random.rand(npoints)*nx)
data_y = 10**(np.random.rand(npoints)*ny-1)
# plot grid then points
plt.pcolor(10.**x, 10.**(y-1), z, edgecolors='k')
plt.loglog(data_x, data_y, '.w')
plt.axis([1,10**5,0.1,10**3])
plt.show()
Note that you could also use zorder=n to force the scatter plot above the image.
I am trying to visualize 3D data. This is a full 3D matrix: each (x,y,z) coordinate has a value, unlike a surface or a collection of individual data vectors. The way I am trying to do this is to plot an opaque cube, where each edge of the cube shows the sum of the data over the orthogonal dimension.
Some example data -- basically, a blob centered at (3,5,7):
import numpy as np
(x,y,z) = np.mgrid[0:10,0:10, 0:10]
data = np.exp(-((x-3)**2 + (y-5)**2 + (z-7)**2)**(0.5))
edge_yz = np.sum(data,axis=0)
edge_xz = np.sum(data,axis=1)
edge_xy = np.sum(data,axis=2)
So the idea would be here to generate a 3D plot that showed a cube; each surface of the cube would show the appropriate 2D matrix edge_*. This would be like plotting 3 4-sided polygons at the appropriate 3D positions (or 6 if you did the back sides of the cube as well) except that each polygon is actually a matrix of values to be plotted in color.
My best approximation at the moment is to compute larger matrices that contained skewed versions of edge, and concatenate these into a single, larger 2D matrix, and imshow() that larger matrix. Seems pretty clumsy, and does a lot of work that some engine in matplotlib or m3plot or something I'm sure already does. It also only works to view a static image at a single view angle, but that's not something I need to overcome at the moment.
Is there a good way to plot these cube edges in a true 3D plot using an existing python tool? Is there a better way to plot a 3D matrix?
Falko's suggestion to use contourf works with a bit of finagling. It's a bit limited since at least my version of contourf has a few bugs where it sometimes renders one of the planes in front of other planes it should be behind, but for now only plotting either the three front or three back sides of the cube will do:
import numpy as np
import math
import matplotlib.pyplot as plot
import mpl_toolkits.mplot3d.axes3d as axes3d
def cube_marginals(cube, normalize=False):
c_fcn = np.mean if normalize else np.sum
xy = c_fcn(cube, axis=0)
xz = c_fcn(cube, axis=1)
yz = c_fcn(cube, axis=2)
return(xy,xz,yz)
def plotcube(cube,x=None,y=None,z=None,normalize=False,plot_front=False):
"""Use contourf to plot cube marginals"""
(Z,Y,X) = cube.shape
(xy,xz,yz) = cube_marginals(cube,normalize=normalize)
if x == None: x = np.arange(X)
if y == None: y = np.arange(Y)
if z == None: z = np.arange(Z)
fig = plot.figure()
ax = fig.gca(projection='3d')
# draw edge marginal surfaces
offsets = (Z-1,0,X-1) if plot_front else (0, Y-1, 0)
cset = ax.contourf(x[None,:].repeat(Y,axis=0), y[:,None].repeat(X,axis=1), xy, zdir='z', offset=offsets[0], cmap=plot.cm.coolwarm, alpha=0.75)
cset = ax.contourf(x[None,:].repeat(Z,axis=0), xz, z[:,None].repeat(X,axis=1), zdir='y', offset=offsets[1], cmap=plot.cm.coolwarm, alpha=0.75)
cset = ax.contourf(yz, y[None,:].repeat(Z,axis=0), z[:,None].repeat(Y,axis=1), zdir='x', offset=offsets[2], cmap=plot.cm.coolwarm, alpha=0.75)
# draw wire cube to aid visualization
ax.plot([0,X-1,X-1,0,0],[0,0,Y-1,Y-1,0],[0,0,0,0,0],'k-')
ax.plot([0,X-1,X-1,0,0],[0,0,Y-1,Y-1,0],[Z-1,Z-1,Z-1,Z-1,Z-1],'k-')
ax.plot([0,0],[0,0],[0,Z-1],'k-')
ax.plot([X-1,X-1],[0,0],[0,Z-1],'k-')
ax.plot([X-1,X-1],[Y-1,Y-1],[0,Z-1],'k-')
ax.plot([0,0],[Y-1,Y-1],[0,Z-1],'k-')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plot.show()
plot_front=True
plot_front=False
Other data (not shown)
Take a look at MayaVI. The contour3d() function may be what you want.
Here's an answer I gave to a similar question with an example of the code and resulting plot https://stackoverflow.com/a/24784471/3419537