首页 > 解决方案 > 使用 matplotlib 绘制时间序列摆动部分

问题描述

我有一个 .mat 文件。我想读取其包含时间序列数据(10 个)的每一列,并希望通过使用 matplotlib 库包并排排列时间序列来制作摆动图部分。其中 x 轴将是时间序列号和y 轴将是时间样本。

我试过下面的脚本

import numpy as np
import h5py
import matplotlib.pyplot as plt


c1 = h5py.File('test_data.mat', 'r')  
out1=c1.get('dat')
for x in range(10):
   dd=out1[x]
   plt.plot(np.arange(len(dd)), dd)
   plt.show()

但它没有给出摆动情节部分。请提出更好的解决方案。谢谢。

标签: python-3.xpandasnumpymatplotlibmatrix

解决方案


在其他库中可能有更简单的方法来执行此操作,但仅使用 matplotlib,您可以使用fill.betweenx和的组合来实现此目的subplots。(大部分其他代码都是为了美观,可以修改以提高可读性或符合您的口味。)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec

dat = np.ndarray(buffer=np.sin(np.random.uniform(size=1000)), shape=(100, 10))
dat[:, [1, 4, 6]] = np.log(dat[:, [1, 4, 6]])

numplots = dat.shape[1]

fig, ax = plt.subplots(1, numplots)
for i in range(numplots):
    # Define series and indexes
    y = dat[:, i]
    ym = y.mean()
    idx = np.arange(len(y))

    # Plot series
    ax[i].plot(y, idx)

    # Fill when series > mean
    ax[i].fill_betweenx(
        idx, y, ym, where=y > y.mean(), color="Orange", interpolate=True
    )

    # Fill when series <= mean
    ax[i].fill_betweenx(idx, y, ym, where=y <= y.mean(), color="Gray", interpolate=True)

    # Optional aesthetics
    ax[i].set_xlabel("Series " + str(i))
    if (i < numplots - 1) & (i > 0):
        ax[i].spines["right"].set_visible(False)
        ax[i].spines["left"].set_visible(False)
        ax[i].yaxis.set_ticks([])

# Final adjustments
ax[0].spines["right"].set_visible(False)
ax[numplots - 1].spines["left"].set_visible(False)
ax[numplots - 1].yaxis.set_ticks([])
plt.subplots_adjust(wspace=0.0)
plt.show()

产生以下内容:在此处输入图像描述

注意水平对齐:我从这张照片中获得灵感。但是,如果您希望绘图水平显示,请使用以下代码更改上面的代码:

fig, ax = plt.subplots(numplots, 1)
for i in range(numplots):
    # Define series and indexes
    y = dat[:, i]
    ym = y.mean()
    idx = np.arange(len(y))
    # Plot series
    ax[i].plot(idx, y)
    # Fill when series > mean
    ax[i].fill_between(idx, y, ym, where=y > y.mean(), color="Orange", interpolate=True)
    # Fill when series <= mean
    ax[i].fill_between(idx, y, ym, where=y <= y.mean(), color="Gray", interpolate=True)
    # Optional aesthetics
    ax[i].set_ylabel("Series " + str(i), rotation=0, labelpad=40)
    ax[i].xaxis.set_ticks([])
    if (i < numplots - 1) & (i > 0):
        ax[i].spines["top"].set_visible(False)
        ax[i].spines["bottom"].set_visible(False)
# Final adjustments
ax[0].spines["bottom"].set_visible(False)
ax[numplots - 1].spines["top"].set_visible(False)
plt.show()

产生这个: 在此处输入图像描述


推荐阅读