【问题标题】:color of a 3D surface plot in pythonpython中3D曲面图的颜色
【发布时间】:2015-12-01 12:23:20
【问题描述】:

我正在使用以下线来绘制 3D 表面:

surf = ax3.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.5, linewidth=0, cmap=cm.jet,antialiased=True)

现在颜色变得非常漂亮,虽然有点鳞片状,但很好。
但我想改变表面颜色w.r.t。另一个数据,存储在list 中:

m = [104.48, 111.73,109.93,139.95,95.05,150.49,136.96,157.75]

我正在尝试:

norm = cls.Normalize() # Norm to map the 'm' values to [0,1]
norm.autoscale(m)
cmap = cm.ScalarMappable(norm, 'jet')
surf = ax3.plot_surface(X, Y, Z, rstride=5, cstride=5, alpha=0.5, linewidth=0, color=cmap.to_rgba(m), antialiased=True)

但这会引发错误,因为cmap.to_rgba 仅采用一维数组。 任何有关如何更改表面的colormap 的建议将不胜感激。

【问题讨论】:

    标签: python matplotlib plot


    【解决方案1】:

    嗯,它看起来很糟糕,但我认为你可以适应它:

    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    from matplotlib.ticker import LinearLocator, FormatStrFormatter
    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)
    my_col = cm.jet(np.random.rand(Z.shape[0],Z.shape[1]))
    
    surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors = my_col,
            linewidth=0, antialiased=False)
    ax.set_zlim(-1.01, 1.01)
    

    我不会使用 jet,而是使用一些线性颜色图,例如 cubehelix。您可以使用错误的颜色图轻松欺骗眼睛(one of many posts 关于该主题)

    【讨论】:

    • 如果我理解正确,那么您正在绘制X,Y,Z 并根据Z-array 为表面提供自定义颜色。但是我已经有了 (X,Y,Z) 的白色表面,我现在要做的就是根据m-array 的值为表面着色。如果我有误解,请纠正我。
    • 您必须在缩放的 m 数组上使用 meshgrid 才能获得二维数组。
    • 是的,我使用np.meshgrid 以防x,y,z 拟合,但它给了我一个矩阵数据(等级为3)传递给plot_surface(X,Y,Z,...) 以生成表面.现在我怎样才能在绘图中处理矩阵等级 4(如果我包括m)?关于你的想法的一点代码会很好。
    • 只要你不提供数组m 和一些工作最小的例子,我只能猜测。
    • @diffracteD,m 与 X、Y 和 Z 有何关系?例如,它是否具有相同数量的元素?你想如何将 m 映射到你的表面上?
    【解决方案2】:

    要获得正确的颜色,请使用 Z 值从颜色图中选择值:

    my_col = cm.jet(Z/np.amax(Z))
    

    结果:

    使用与@Moritz 相同的代码。

    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    from matplotlib.ticker import LinearLocator, FormatStrFormatter
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.add_subplot(111, 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)
    my_col = cm.jet(Z/np.amax(Z))
    
    surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors = my_col,
            linewidth=0, antialiased=False)
    ax.set_zlim(-1.01, 1.01)
    
    plt.show()
    

    【讨论】:

    • 有什么方法可以去除情节的鳞片外观并获得光泽外观?
    • 您必须将数据插入到更精细的网格中。
    • @diffracteD 正是@Moritz 所说的。将 np.arange(-5, 5, 0.25) 中的 0.25 更改为较低的值。
    • @pingul 我会回复你关于鳞片状的外观。但更重要的是,我关心的是使用 m 值作为 XYZ 表面上的颜色图。请对此问题发表评论。
    • @diffracteD 您需要为每个 Z 值指定一个颜色值,即 m 需要包含与 Z 相同的尺寸(检查 Z.shape == m.shape)。如果是这种情况,只需将代码更改为my_col = cm.jet(m/np.amax(m)) 即可对其进行规范化。
    【解决方案3】:

    我用 PANDAS 在 python 中做了一些线,情节很漂亮!

    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    from matplotlib import cm
    import numpy as np
    import pandas as pd
    from sys import argv
    
    file = argv[1]
    
    x,y,z = np.loadtxt(file, unpack=True)
    df = pd.DataFrame({'x': x, 'y': y, 'z': z})
    
    fig = plt.figure()
    ax = Axes3D(fig)
    surf = ax.plot_trisurf(df.x, df.y, df.z, cmap=cm.jet, linewidth=0.1)
    fig.colorbar(surf, shrink=0.5, aspect=5)
    plt.savefig('teste.pdf')
    plt.show()
    

    Collapsing wave equations

    更漂亮一点!在我的例子中,我使用颜色图 JET Colormaps Matplotlib,但还有其他种类的颜色和定性图。看看之前的链接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      相关资源
      最近更新 更多