首页 > 解决方案 > 带有 datetime64[ns] 轴的 Matplotlib 多色线

问题描述

这是我正在尝试完成的简化版本。我正在关注matplotlib 网站上的这个彩色线条示例

我正在尝试绘制一组时间序列数据,其中线根据不同的数组着色。在下面的简单示例中,我正在绘制 y=x^2,线条根据其导数 dy/dx = 2x 进行着色。

当我使用只有浮点数的 x 轴时,如下所示,它工作正常。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

# Generate data
x = np.linspace(0,10, 60)
y = x ** 2
dydx = 2*x

# Create arrays needed for multicolored lines
points = np.array([x, y]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
norm = plt.Normalize(dydx.min(), dydx.max())

# Plot
fig, ax = plt.subplots(1,1, figsize=(10,10))

lc = LineCollection(segments, cmap='jet', norm=norm)
lc.set_array(dydx)
lc.set_linewidth(2)
line = ax.add_collection(lc)
fig.colorbar(line, ax=ax)

ax.set_xlim(x.min(), x.max())
ax.set_ylim(y.min(), y.max())
plt.show()

哪个生产

带有阴影导数的 y=x^2 的工作图

但是,如果我试图绘制时间序列数据(其中 x 轴是 datetime64[ns] 数组),它就行不通。在下面的示例中,我将 x 替换为 x_time。

# Generate time array
ts = np.datetime64('2020-01-01T00:00:00')
te = np.datetime64('2020-01-01T01:00:00')
x_time = np.arange(ts, te, np.timedelta64(1,'m'), dtype='datetime64[ns]')

# Create arrays needed for multicolored lines
points = np.array([x_time, y]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
norm = plt.Normalize(dydx.min(), dydx.max())

# Plot
fig, ax = plt.subplots(1,1, figsize=(10,10))

lc = LineCollection(segments, cmap='jet', norm=norm)
lc.set_array(dydx)
lc.set_linewidth(2)
line = ax.add_collection(lc)
fig.colorbar(line, ax=ax)

ax.set_xlim(x_time.min(), x_time.max())
ax.set_ylim(y.min(), y.max())
plt.show()

这会产生一个右 x 任何 y 轴刻度的图形,但没有线

在此处输入图像描述

编辑:好的,我弄清楚了线路的去向。当我创建segments数组时,它将转换datetime64[ns]为整数表示。通常,matplotlib 能够将其解释为日期时间,但在这种情况下,由于LineCollection,它将其保留为 int

设置ax.set_xlim(segments[:,:,0].min(), segments[:,:,0].max())显示我的线,但轴是错误的(不显示为时间)。 在此处输入图像描述

标签: pythonnumpymatplotlib

解决方案


您将需要

  1. 将日期转换为代表 matplotlib 日期时间格式的数字
  2. 告诉轴它应该勾选日期时间。

所以:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import matplotlib.dates as mdates
# Generate data
x = np.linspace(0,10, 60)
y = x ** 2
dydx = 2*x

# Generate time array
ts = np.datetime64('2020-01-01T00:00:00')
te = np.datetime64('2020-01-01T01:00:00')
x_time = np.arange(ts, te, np.timedelta64(1,'m'), dtype='datetime64[ns]')
x_time = mdates.date2num(x_time)
# Create arrays needed for multicolored lines
points = np.array([x_time, y]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
norm = plt.Normalize(dydx.min(), dydx.max())

# Plot
fig, ax = plt.subplots(1,1, figsize=(10,10))

lc = LineCollection(segments, cmap='jet', norm=norm)
lc.set_array(dydx)
lc.set_linewidth(2)
line = ax.add_collection(lc)
fig.colorbar(line, ax=ax)

ax.xaxis_date()
ax.autoscale()

plt.show()

推荐阅读