Reputation: 858
I learned to merge mesh grid points from two rectangles in python from this question. The merged grid points are:
Here each grid points contains their respective values and I want to plot a 3-D surface plot of it. For the full grid (without blank spot), I'd write the following code:
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x=np.arange(0,10,1)
y=np.arange(0,12,1)
X, Y = np.meshgrid(x,y)
print (Y)
Z = gridValue.reshape(X.shape)
cset = ax.pcolormesh(X, Y, Z, cmap=cm.coolwarm, linewidth =0, antialiased = False)
ax.clabel(cset, fontsize=9, inline=1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('σ ')
fig.colorbar(cset, shrink=0.5, aspect =5)
plt.show()
When I try to plot the grid values (80 points) with above code, I get an obvious error:
ValueError: cannot reshape array of size 80 into shape (12,10)
I'm expecting the following figure (not exactly but similar way) as the final 3-D surface plot:
How can I draw a 3-D surface plot is my situation?
Thank you.
EDIT: I tried to plot using the following code snippet:
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x1=np.arange(0,2,1)
x2 = np.arange(0,10,1)
y1 =np.arange(0,5,1)
y2=np.arange(5,12,1)
Y1, X1 = np.meshgrid(x1,y1)
Y2, X2 = np.meshgrid(x2,y2)
gridValue1 = gridValue[:10]
gridValue2 = gridValue[10:]
Z1 = gridValue1.reshape(X1.shape)
Z2 = gridValue2.reshape(X2.shape)
cset1 = ax.plot_surface(X1, Y1, Z1, cmap=cm.coolwarm, linewidth =0, antialiased = False)
cset2 = ax.plot_surface(X2, Y2, Z2, cmap=cm.coolwarm, linewidth =0, antialiased = False)
ax.clabel(cset1, fontsize=9, inline=1)
ax.clabel(cset2, fontsize=9, inline=1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('σ ')
plt.show()
I got following figure with this code:
Now the problem is to illustrate the figure. The color code (red color for high value, blue color for low value) is not valid any longer. Because the gridValues
of blue gird points (in the first figure) are high, so most of them should have red color in the surface plot. So merging two individual 3-D surface plots is not the solution to my problem. Any help, please!
Upvotes: 1
Views: 580
Reputation: 5774
If your gridValue
array is larger than your meshgrid with (12,10)
you need to interpolate gridValue
to the correct shape.
In your case, since I guess that you want to plot the shown shapes with 80
points, you need to construct an array for gridValue
with the shape of the meshgrid and then distribute your 80 grid values to the correct positions of the gridValue
array with shape (12,10)
. How you can do the distribution fully depends on the information that you have, thus unluckily I can't help you with that. But for example considering a y-sorted sequential distribution of the blue and green grids:
gridValue_new = np.zeros_like(X)
gridValue_new[:, 0] = gridValue[:12]
gridValue_new[:, 1] = gridValue[12:24]
gridValue_new.reshape(-1)[:8, 2:] = gridValue[24:]
The first two ligns distributing points could also be rewritten using reshape()
.
If you want to plot it in 2d, use pcolormesh
.
For 3d-plotting, using ax.plot_surface()
will fit your needs.
If you want to plot both grids in one axis, do the following:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
X, Y = np.meshgrid(np.arange(0, 10, 1), np.arange(0, 12, 1))
X1 = X[5:, :]
Y1 = Y[5:, :]
X2 = X[0:5, 0:2]
Y2 = Y[0:5, 0:2]
Z1 = np.random.rand(7, 10) # generating some random grid values
Z2 = np.random.rand(5, 2)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X1, Y1, Z1)
ax.plot_surface(X2, Y2, Z2)
To get the correct colorbar, get the min/max values of your array:
vmin = gridValue.min()
vmax = gridValue.max()
and pass both as argument to plot_surface()
:
cset1 = ax.plot_surface(X1, Y1, Z1, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
cset2 = ax.plot_surface(X2, Y2, Z2, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
So your full code will look like this:
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x1=np.arange(0,2,1)
x2 = np.arange(0,10,1)
y1 =np.arange(0,5,1)
y2=np.arange(5,12,1)
Y1, X1 = np.meshgrid(x1,y1)
Y2, X2 = np.meshgrid(x2,y2)
gridValue1 = gridValue[:10]
gridValue2 = gridValue[10:]
Z1 = gridValue1.reshape(X1.shape)
Z2 = gridValue2.reshape(X2.shape)
vmin = gridValue.min()
vmax = gridValue.max()
cset1 = ax.plot_surface(X1, Y1, Z1, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
cset2 = ax.plot_surface(X2, Y2, Z2, cmap=cm.coolwarm, linewidth =0, antialiased = False, vmin=vmin, vmax=vmax)
ax.clabel(cset1, fontsize=9, inline=1)
ax.clabel(cset2, fontsize=9, inline=1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('σ ')
plt.show()
Upvotes: 2