and*_*rea 2 python 3d matplotlib
我正在尝试绘制一个三维表面,其中三个维度中的每个维度在一个单独的数组中,每个坐标处的表面着色是x,y,z的函数.一种numpy.pcolormesh,但在4D,而不是3D.3D图由下式给出:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig = plt.figure()
ax = fig.gca(projection='3d')
x = np.logspace(-1.,np.log10(5),50)
y = np.linspace(6,9,50)
z = np.linspace(-1,1,50)
colors = LikeBeta(y,range(50),range(50))
ax.plot_trisurf(x,y,z,cmap=colors,linewidth=0.2)
Run Code Online (Sandbox Code Playgroud)
哪里
def LikeBeta(rho0,r0,beta):
M0 = 10**rho0*r0_array[r0]**3
I = cst*M0*sigma_los_beta[beta,:,r0]
S = dv**2+I
res = (np.log(S) + (v-u)**2/S).sum()
return res/2.
Run Code Online (Sandbox Code Playgroud)
可能cmap=colors是错的,但问题出在其他地方.我收到以下错误:
----> 8 colors = LikeBeta(y,range(50),range(50))
----> 4 I = cst*M0*sigma_los_beta[beta,:,r0]
ValueError: operands could not be broadcast together with shapes (50,) (50,353)
Run Code Online (Sandbox Code Playgroud)
确实sigma_los_beta是一个我单独评估并具有形状的阵列,(50,353,50)而那些353是我必须拥有的数据.
如何将此函数转换为与其他条目兼容的表单plot_trisurf?
抱歉,我无法提供最小的工作代码,因为dv,v和u是数据.非常感谢您的帮助.干杯
Fri*_*rik 10
这个答案解决了4d曲面图问题.它使用matplotlib的plot_surface函数代替plot_trisurf.
基本上,您希望将x,y和z变量重塑为相同维度的2d数组.要将第四个维度添加为色彩映射,必须提供与轴变量具有相同维度的另一个二维数组.
下面是3d图的示例代码,其中colormap对应于x值.该facecolors参数用于根据您的喜好改变色彩映射.请注意,其值是从类中的to_rgba()函数获取的matplotlib.cm.ScalarMappable.
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
# domains
x = np.logspace(-1.,np.log10(5),50) # [0.1, 5]
y = np.linspace(6,9,50) # [6, 9]
z = np.linspace(-1,1,50) # [-1, 1]
# convert to 2d matrices
Z = np.outer(z.T, z) # 50x50
X, Y = np.meshgrid(x, y) # 50x50
# fourth dimention - colormap
# create colormap according to x-value (can use any 50x50 array)
color_dimension = X # change to desired fourth dimension
minn, maxx = color_dimension.min(), color_dimension.max()
norm = matplotlib.colors.Normalize(minn, maxx)
m = plt.cm.ScalarMappable(norm=norm, cmap='jet')
m.set_array([])
fcolors = m.to_rgba(color_dimension)
# plot
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X,Y,Z, rstride=1, cstride=1, facecolors=fcolors, vmin=minn, vmax=maxx, shade=False)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
fig.canvas.show()
Run Code Online (Sandbox Code Playgroud)
我引用的答案(和其他人)提到您应该规范化您的第四维数据.似乎可以通过显式设置色彩映射的限制来避免这种情况,就像我在代码示例中所做的那样.
非常感谢@Frik 的出色回答,它帮助我实现了 OP 要求的类似情节。
但是,我发现可以对代码进行一些简化并且可能会引起兴趣。片段和下图。
import matplotlib.pyplot as plt
# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused import
from mpl_toolkits.mplot3d.axes3d import get_test_data
import numpy as np
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
X, Y, Z = get_test_data(0.05)
C = np.linspace(-5, 5, Z.size).reshape(Z.shape)
scamap = plt.cm.ScalarMappable(cmap='inferno')
fcolors = scamap.to_rgba(C)
ax.plot_surface(X, Y, Z, facecolors=fcolors, cmap='inferno')
fig.colorbar(scamap)
plt.show()
Run Code Online (Sandbox Code Playgroud)
最后,我还想评论@Frik 所写的内容:
我引用(和其他人)的答案提到您应该规范化您的第四维数据。似乎可以通过像我在代码示例中所做的那样显式设置颜色图的限制来避免这种情况。
我发现这个说法是不正确的。确实,如果您查看to_rgba,就会发现有一个norm关键字默认设置为True。这正是规范化发生的地方。还包括以下声明:
如果 norm 为 False,则不对输入数据进行归一化,并假定它在 (0-1) 范围内。
您确实希望您的数据位于 (0-1) 中。
| 归档时间: |
|
| 查看次数: |
9147 次 |
| 最近记录: |