问题描述
我想将 MATLAB 中的surf命令转换为 matplotlib 中的plot_surface命令.
I would like to convert surf command from MATLAB to plot_surface command in matplotlib.
我面临的挑战是在plot_surface命令中使用 cmap 函数对表面进行渐变着色时.
The challenge I am facing is when using cmap function in plot_surface command to color the surface with gradient.
这是 matlab 脚本
% Matlab Commands
x = -5:.25:5; y = x
[x,y] = meshgrid(x);
R = sqrt(x.^2 + y.^2);
Z = sin(R)
surf(x,y,Z,gradient(Z))
可以在此处找到该命令的图形. (http://www.mathworks.com/help/techdoc/visualize/f0 -18164.html#f0-46458)
The figure from such a command can be found here. (http://www.mathworks.com/help/techdoc/visualize/f0-18164.html#f0-46458)
这是 python 的内容当使用python和matplotlib创建类似的函数时,我无法使用渐变为表面着色.
Here is the python sciptWhen using python and matplotlib to create a similar function I am unable to color the surface with a gradient.
# Python-matplotlib Commands
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=gradient(Z), linewidth=0, antialiased=False)
plt.show()
我收到以下错误消息:
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
File "C:\Python26\lib\site-packages\spyderlib\widgets\externalshell\startup.py", line 122, in runfile
execfile(filename, glbs)
File "C:\Documents and Settings\mramacha\My Documents\Python\Candela\tmp.py", line 13, in <module>
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=gradient(Z), linewidth=0, antialiased=False)
File "C:\Python26\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 729, in plot_surface
polyc = art3d.Poly3DCollection(polys, *args, **kwargs)
File "C:\Python26\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 344, in __init__
PolyCollection.__init__(self, verts, *args, **kwargs)
File "C:\Python26\lib\site-packages\matplotlib\collections.py", line 570, in __init__
Collection.__init__(self,**kwargs)
File "C:\Python26\lib\site-packages\matplotlib\collections.py", line 86, in __init__
cm.ScalarMappable.__init__(self, norm, cmap)
File "C:\Python26\lib\site-packages\matplotlib\cm.py", line 155, in __init__
self.cmap = get_cmap(cmap)
File "C:\Python26\lib\site-packages\matplotlib\cm.py", line 126, in get_cmap
if name in cmap_d:
TypeError: unhashable type: 'list'
任何输入都会有所帮助.
Any inputs would be helpful.
Praboo
推荐答案
首先,您似乎希望从渐变幅度映射颜色.您正在尝试使用梯度向量,这就是为什么出现列表"错误的原因.
First, it looks like you want the colors mapped from gradient magnitude. You are trying to use the gradient vectors which is why you are getting the 'list' error.
第二,您可以提供一个cmap,但是它仅定义了如何将Z值映射到一种颜色.如果您想要新的脸色,请使用 facecolors
参数
Second, you can supply a cmap, but it only defines how you want the Z values mapped to a color. If you want new face colors then use the facecolors
argument.
第三,您需要将值归一化为0..1,然后通过颜色图将它们映射. (我认为还有另一种方法,但是将幅度除以最大值非常简单)
Third, you'll want to normalize the values to 0..1 then map them thru a colormap. (I think there is another way, but dividing the magnitude by the max is pretty simple)
代码如下:
# Python-matplotlib Commands
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, .25)
Y = np.arange(-5, 5, .25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
Gx, Gy = np.gradient(Z) # gradients with respect to x and y
G = (Gx**2+Gy**2)**.5 # gradient magnitude
N = G/G.max() # normalize 0..1
surf = ax.plot_surface(
X, Y, Z, rstride=1, cstride=1,
facecolors=cm.jet(N),
linewidth=0, antialiased=False, shade=False)
plt.show()
结果:
这篇关于使用表面渐变颜色的matplotlib plot_surface命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!