非矩形域上的 Python 3D 图 [英] Python 3D Plots over non-rectangular domain
问题描述
我有一些我想绘制的 z=f(x,y)
数据.问题是 (x,y)
不是漂亮"矩形的一部分,而是任意平行四边形,如附图所示(这个特殊的也是一个矩形,但你可以认为更一般的情况).所以我很难弄清楚在这种情况下如何使用 plot_surface
,因为这通常将 x 和 y 作为二维数组,而这里我的 x 和 y 值是 1d.谢谢.
Abritrary 点可以作为一维数组提供给
为了完整起见,请在此处找到生成上图的代码:
将 matplotlib.pyplot 导入为 plt从 mpl_toolkits.mplot3d 导入 Axes3D将 numpy 导入为 npf = λ x,y: np.sin(x+0.4*y)*0.23+1fig = plt.figure(figsize=(5,6))plt.subplots_adjust(left=0.1, top=0.95,wspace=0.01)ax0 = fig.add_subplot(322, 投影=3d")ma = 6*(np.random.rand(100)-0.5)mb = 6*(np.random.rand(100)-0.5)phi = np.pi/4x = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi)y = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi)z = f(x,y)ax0.plot_trisurf(x,y,z)ax1 = fig.add_subplot(321)ax0.set_title("随机 plot_trisurf()")ax1.set_aspect("相等")ax1.scatter(x,y, 标记="+", alpha=0.4)对于范围内的 i(len(x)):ax1.text(x[i],y[i], i, ha="center", va="center", fontsize=6)n = 10a = np.linspace(-3, 3, n)ma, mb = np.meshgrid(a,a)phi = np.pi/4xm = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi)ym = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi)shuf = np.c_[xm.flatten(), ym.flatten()]np.random.shuffle(shuf)x = shuf[:,0]y = shuf[:,1]z = f(x,y)ax2 = fig.add_subplot(324, 投影=3d")ax2.plot_trisurf(x,y,z)ax3 = fig.add_subplot(323)ax2.set_title("非结构化 plot_trisurf()")ax3.set_aspect("相等")ax3.scatter(x,y, 标记="+", alpha=0.4)对于范围内的 i(len(x)):ax3.text(x[i],y[i], i, ha="center", va="center", fontsize=6)x = xm.flatten()y = ym.flatten()z = f(x,y)X = x.reshape(10,10)Y = y.reshape(10,10)Z = z.reshape(10,10)ax4 = fig.add_subplot(326, 投影=3d")ax4.plot_surface(X,Y,Z)ax5 = fig.add_subplot(325)ax4.set_title("常规 plot_surf()")ax5.set_aspect("相等")ax5.scatter(x,y, 标记="+", alpha=0.4)对于范围内的 i(len(x)):ax5.text(x[i],y[i], i, ha="center", va="center", fontsize=6)对于 [ax0, ax2,ax4] 中的轴:axis.set_xlim([-3.5,3.5])axis.set_ylim([-3.5,3.5])axis.set_zlim([0.9,2.0])轴.轴(关闭")plt.savefig(__file__+".png")plt.show()
I have some z=f(x,y)
data which i would like to plot. The issue is that (x,y)
are not part of a "nice" rectangle, but rather arbitrary parallelograms, as shown in the attached image (this particular one is also a rectangle, but you could think of more general cases). So I am having a hard time figuring out how I can use plot_surface
in this case, as this usually will take x and y as 2d arrays, and here my x-and y-values are 1d. Thanks.
Abritrary points can be supplied as 1D arrays to matplotlib.Axes3D.plot_trisurf
. It doesn't matter whether they follow a specific structure.
Other methods which would depend on the structure of the data would be
- Interpolate the points on a regular rectangular grid. This can be accomplished using
scipy.interpolate.griddata
. See example here - Reshape the input arrays such that they live on a regular and then use
plot_surface()
. Depending on the order by which the points are supplied, this could be a very easy solution for a grid with "parallelogramic" shape.
As can be seen from the sphere example,plot_surface()
also works in cases of very unequal grid shapes, as long as it's structured in a regular way.
Here are some examples:
For completeness, find here the code that produces the above image:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
f = lambda x,y: np.sin(x+0.4*y)*0.23+1
fig = plt.figure(figsize=(5,6))
plt.subplots_adjust(left=0.1, top=0.95,wspace=0.01)
ax0 = fig.add_subplot(322, projection="3d")
ma = 6*(np.random.rand(100)-0.5)
mb = 6*(np.random.rand(100)-0.5)
phi = np.pi/4
x = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi)
y = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi)
z = f(x,y)
ax0.plot_trisurf(x,y,z)
ax1 = fig.add_subplot(321)
ax0.set_title("random plot_trisurf()")
ax1.set_aspect("equal")
ax1.scatter(x,y, marker="+", alpha=0.4)
for i in range(len(x)):
ax1.text(x[i],y[i], i , ha="center", va="center", fontsize=6)
n = 10
a = np.linspace(-3, 3, n)
ma, mb = np.meshgrid(a,a)
phi = np.pi/4
xm = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi)
ym = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi)
shuf = np.c_[xm.flatten(), ym.flatten()]
np.random.shuffle(shuf)
x = shuf[:,0]
y = shuf[:,1]
z = f(x,y)
ax2 = fig.add_subplot(324, projection="3d")
ax2.plot_trisurf(x,y,z)
ax3 = fig.add_subplot(323)
ax2.set_title("unstructured plot_trisurf()")
ax3.set_aspect("equal")
ax3.scatter(x,y, marker="+", alpha=0.4)
for i in range(len(x)):
ax3.text(x[i],y[i], i , ha="center", va="center", fontsize=6)
x = xm.flatten()
y = ym.flatten()
z = f(x,y)
X = x.reshape(10,10)
Y = y.reshape(10,10)
Z = z.reshape(10,10)
ax4 = fig.add_subplot(326, projection="3d")
ax4.plot_surface(X,Y,Z)
ax5 = fig.add_subplot(325)
ax4.set_title("regular plot_surf()")
ax5.set_aspect("equal")
ax5.scatter(x,y, marker="+", alpha=0.4)
for i in range(len(x)):
ax5.text(x[i],y[i], i , ha="center", va="center", fontsize=6)
for axes in [ax0, ax2,ax4]:
axes.set_xlim([-3.5,3.5])
axes.set_ylim([-3.5,3.5])
axes.set_zlim([0.9,2.0])
axes.axis("off")
plt.savefig(__file__+".png")
plt.show()
这篇关于非矩形域上的 Python 3D 图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!