简体   繁体   English

Matplotlib:将 plot_surface 中的 cmap 设置为 x 和 y 轴

[英]Matplotlib: Set cmap in plot_surface to x and y-axes

How can I set the colormap in relation to the radius of the figure?如何设置与图形半径相关的颜色图?

And how can I close the ends of the cylinder (on the element, not the top and bottom bases)?我怎样才能关闭圆柱体的末端(在元件上,而不是顶部和底部)?

My script:我的脚本:

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from math import sin, cos, pi

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

h, w = 60,30
znew = np.random.randint(low=90, high=110, size=(60,30))
theta = np.linspace(0,2*pi, h)
Z = np.linspace(0,1,w)

Z,theta = np.meshgrid(Z, theta)

R = 1
X = (R*np.cos(theta))*znew
Y = (R*np.sin(theta))*znew


ax1 = ax.plot_surface(X,Y,Z,linewidth = 0, cmap="coolwarm",              
vmin= 80,vmax=130, shade = True, alpha = 0.75)

fig.colorbar(ax1, shrink=0.9, aspect=5)

plt.show()

在此处输入图片说明

First you need to use the facecolors keyword argument of plot_surface to draw your surface with arbitrary (non- Z -based) colours.首先,你需要使用facecolors关键字参数plot_surface与任意(非提请表面Z为基础)的颜色。 You have to pass an explicit RGBA colour four each point, which means we need to sample a colormap object with the keys given by the radius at every point.您必须为每个点传递一个显式的 RGBA 颜色 4,这意味着我们需要使用每个点的半径给定的键对颜色图对象进行采样。 Finally, this will break the mappable property of the resulting surface, so we will have to construct the colorbar by manually telling it to use our radii for colours:最后,这将破坏结果表面的可映射属性,因此我们必须通过手动告诉它使用我们的半径来构建颜色条:

import numpy as np
from matplotlib import pyplot as plt
import matplotlib.cm as cm
from matplotlib.colors import Normalize
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

h, w = 60,30
#znew = np.random.randint(low=90, high=110, size=(h,w))
theta = np.linspace(0,2*np.pi, h)
Z = np.linspace(0,1,w)

Z,theta = np.meshgrid(Z, theta)
znew = 100 + 10*np.cos(theta/2)*np.cos(2*Z*np.pi)

R = 1
X = (R*np.cos(theta))*znew
Y = (R*np.sin(theta))*znew
true_radius = np.sqrt(X**2 + Y**2)
norm = Normalize()
colors = norm(true_radius) # auto-adjust true radius into [0,1] for color mapping

cmap = cm.get_cmap("coolwarm")
ax.plot_surface(X, Y, Z, linewidth=0, facecolors=cmap(colors), shade=True, alpha=0.75)

# the surface is not mappable, we need to handle the colorbar manually
mappable = cm.ScalarMappable(cmap=cmap)
mappable.set_array(colors)
fig.colorbar(mappable, shrink=0.9, aspect=5)

plt.show()

Note that I changed the radii to something smooth for a less chaotic-looking result.请注意,我将半径更改为平滑的东西,以减少看起来混乱的结果。 The true_radius arary contains the actual radii in data units, which after normalization becomes colors (essentially colors = (true_radius - true_radius.min())/true_radius.ptp() ). true_radius数组包含数据单元中的实际半径,归一化后变为colors (本质上是colors = (true_radius - true_radius.min())/true_radius.ptp() )。

The result:结果:

与预期的颜色一样的漂亮结果

Finally, note that I generated the radii such that the cylinder doesn't close seamlessly.最后,请注意我生成的半径使得圆柱体不会无缝闭合。 This mimicks your random example input.这模仿您的随机示例输入。 There's nothing you can do about this as long as the radii are not 2π-periodic in theta .没有什么,只要半径不2π周期,你可以做这个theta This has nothing to do with visualization, this is geometry.这与可视化无关,这是几何。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM