带彩色高度的 Matplotlib 3D 瀑布图

Posted

技术标签:

【中文标题】带彩色高度的 Matplotlib 3D 瀑布图【英文标题】:Matplotlib 3D Waterfall Plot with Colored Heights 【发布时间】:2018-03-04 03:15:59 【问题描述】:

我正在尝试使用 Python 和 Matplotlib 以 3D 形式可视化一个数据集,该数据集由 x-z 数据的时间序列(沿 y)组成。

我想创建一个像下面这样的图(它是用 Python 制作的:http://austringer.net/wp/index.php/2011/05/20/plotting-a-dolphin-biosonar-click-train/),但是颜色随 Z 变化 - 即,强度由颜色图和峰高显示, 为清楚起见。

在 Z 中显示颜色图的示例是(显然是使用 MATLAB 制作的):

可以使用 MATLAB 中的瀑布图选项创建此效果,但我知道 Python 中没有直接等效的效果。

我也尝试过在 Python 中使用 plot_surface 选项(如下),效果不错,但我想“强制”在表面上运行的线仅在 x 方向上(即让它看起来更像堆叠的时间序列而不是表面)。这可能吗?

非常欢迎任何帮助或建议。谢谢。

【问题讨论】:

您与 matplotlib 的关系如何?我认为您将处于其当前能力的边缘。如果可以接受 mayavi,these answers 可能会有所帮助。 Waterfall plot python?的可能重复 【参考方案1】:

我已经生成了一个在 matplotlib 中复制 matlab 瀑布行为的函数,但我认为它在性能方面并不是最好的解决方案。

我从 matplotlib 文档中的两个示例开始:multicolor lines 和 multiple lines in 3d plot。从这些示例中,我只看到可以根据示例后面的 z 值绘制颜色在给定颜色图之后变化的线条,这正在重塑输入数组以通过 2 个点的线段绘制线并将线段的颜色设置为两点之间的 z 平均值。

因此,给定输入矩阵n,m 矩阵XYZ,函数在n,m 之间的最小维度上循环,以绘制示例中的每条线,按2 个点分段,其中按段绘制的整形是使用与示例相同的代码对数组进行整形。

def waterfall_plot(fig,ax,X,Y,Z):
    '''
    Make a waterfall plot
    Input:
        fig,ax : matplotlib figure and axes to populate
        Z : n,m numpy array. Must be a 2d array even if only one line should be plotted
        X,Y : n,m array
    '''
    # Set normalization to the same values for all plots
    norm = plt.Normalize(Z.min().min(), Z.max().max())
    # Check sizes to loop always over the smallest dimension
    n,m = Z.shape
    if n>m:
        X=X.T; Y=Y.T; Z=Z.T
        m,n = n,m

    for j in range(n):
        # reshape the X,Z into pairs 
        points = np.array([X[j,:], Z[j,:]]).T.reshape(-1, 1, 2)
        segments = np.concatenate([points[:-1], points[1:]], axis=1)        
        lc = LineCollection(segments, cmap='plasma', norm=norm)
        # Set the values used for colormapping
        lc.set_array((Z[j,1:]+Z[j,:-1])/2)
        lc.set_linewidth(2) # set linewidth a little larger to see properly the colormap variation
        line = ax.add_collection3d(lc,zs=(Y[j,1:]+Y[j,:-1])/2, zdir='y') # add line to axes

    fig.colorbar(lc) # add colorbar, as the normalization is the same for all, it doesent matter which of the lc objects we use

因此,可以使用与 matplotlib 曲面图相同的输入矩阵轻松生成看起来像 matlab 瀑布的图:

import numpy as np; import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from mpl_toolkits.mplot3d import Axes3D

# Generate data
x = np.linspace(-2,2, 500)
y = np.linspace(-2,2, 40)
X,Y = np.meshgrid(x,y)
Z = np.sin(X**2+Y**2)
# Generate waterfall plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
waterfall_plot(fig,ax,X,Y,Z) 
ax.set_xlabel('X') ; ax.set_xlim3d(-2,2)
ax.set_ylabel('Y') ; ax.set_ylim3d(-2,2)
ax.set_zlabel('Z') ; ax.set_zlim3d(-1,1)

该函数假设在生成网格网格时,x 数组是最长的,默认情况下,线条的 y 是固定的,而 x 坐标是变化的。但是,如果 y 维度的大小较大,则矩阵会被转置,从而生成具有固定 x 的线。因此,生成大小反转的网格(len(x)=40len(y)=500)会产生:

【讨论】:

以上是关于带彩色高度的 Matplotlib 3D 瀑布图的主要内容,如果未能解决你的问题,请参考以下文章

matplotlib绘制柱状图数字后缀带万字怎么画图

如果高度为零,Matplotlib 在 bar3d 中隐藏栏

如何调整 PlotWidget 的高度?

用Matplotlib绘制渐变的彩色曲线

用Matplotlib绘制渐变的彩色曲线

用Matplotlib绘制渐变的彩色曲线