如果 x 轴是熊猫的日期时间索引,如何绘制多色线

2025-04-15 09:20:00
admin
原创
34
摘要:问题描述:我正在尝试使用 Pandas 系列绘制一条多色线。我知道matplotlib.collections.LineCollection这会大大提高效率。但是 LineCollection 要求线段必须是浮点型。我想使用 Pandas 的 datatime 索引作为 x 轴。points = np.arr...

问题描述:

我正在尝试使用 Pandas 系列绘制一条多色线。我知道matplotlib.collections.LineCollection这会大大提高效率。但是 LineCollection 要求线段必须是浮点型。我想使用 Pandas 的 datatime 索引作为 x 轴。

points = np.array((np.array[df_index.astype('float'), values]).T.reshape(-1,1,2))
segments = np.concatenate([points[:-1],points[1:]], axis=1)
lc = LineCollection(segments)
fig = plt.figure()
plt.gca().add_collection(lc)
plt.show()

但是图片不能让我满意。有什么解决办法吗?


解决方案 1:

要生成多色线条,您需要先将日期转换为数字,因为 matplotlib 内部仅适用于数字值。

对于 matplotlib 提供的转换matplotlib.dates.date2num。它可以理解 datetime 对象,因此您首先需要使用 将时间序列转换为 datetime series.index.to_pydatetime(),然后应用date2num

s = pd.Series(y, index=dates)
inxval = mdates.date2num(s.index.to_pydatetime())

然后,您可以照常使用数字点,例如绘制为 Polygon 或 LineCollection[ 1 , 2 ]。

完整示例:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
from matplotlib.collections import LineCollection

dates = pd.date_range("2017-01-01", "2017-06-20", freq="7D" )
y = np.cumsum(np.random.normal(size=len(dates)))

s = pd.Series(y, index=dates)

fig, ax = plt.subplots()

#convert dates to numbers first
inxval = mdates.date2num(s.index.to_pydatetime())
points = np.array([inxval, s.values]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1],points[1:]], axis=1)

lc = LineCollection(segments, cmap="plasma", linewidth=3)
# set color to date values
lc.set_array(inxval)
# note that you could also set the colors according to y values
# lc.set_array(s.values)
# add collection to axes
ax.add_collection(lc)


ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_minor_locator(mdates.DayLocator())
monthFmt = mdates.DateFormatter("%b")
ax.xaxis.set_major_formatter(monthFmt)
ax.autoscale_view()
plt.show()

在此处输入图片描述


由于人们似乎难以理解这个概念,下面是一段与上面相同的代码,但没有使用熊猫,而是使用了一个独立的颜色数组:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np; np.random.seed(42)
from matplotlib.collections import LineCollection

dates = np.arange("2017-01-01", "2017-06-20", dtype="datetime64[D]" )
y = np.cumsum(np.random.normal(size=len(dates)))
c = np.cumsum(np.random.normal(size=len(dates)))


fig, ax = plt.subplots()

#convert dates to numbers first
inxval = mdates.date2num(dates)
points = np.array([inxval, y]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1],points[1:]], axis=1)

lc = LineCollection(segments, cmap="plasma", linewidth=3)
# set color to date values
lc.set_array(c)
ax.add_collection(lc)

ax.xaxis_date()
ax.autoscale_view()
plt.show()

解决方案 2:

ImportanceOfBeingErnest 的答案非常好,帮我省了很多时间。我想分享一下我如何利用上面的答案,根据 Pandas DataFrame 中的信号改变颜色。

import matplotlib.dates as mdates
# import matplotlib.pyplot as plt
# import numpy as np
# import pandas as pd
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm

制作测试 DataFrame

equity = pd.DataFrame(index=pd.date_range('20150701', periods=150))
equity['price'] = np.random.uniform(low=15500, high=18500, size=(150,))
equity['signal'] = 0
equity.signal[15:45] = 1
equity.signal[60:90] = -1
equity.signal[105:135] = 1

# Create a colormap for crimson, limegreen and gray and a norm to color
# signal = -1 crimson, signal = 1 limegreen, and signal = 0 lightgray
cmap = ListedColormap(['crimson', 'lightgray', 'limegreen'])
norm = BoundaryNorm([-1.5, -0.5, 0.5, 1.5], cmap.N)

# Convert dates to numbers
inxval = mdates.date2num(equity.index.to_pydatetime())

# Create a set of line segments so that we can color them individually
# This creates the points as a N x 1 x 2 array so that we can stack points
# together easily to get the segments. The segments array for line collection
# needs to be numlines x points per line x 2 (x and y)
points = np.array([inxval, equity.price.values]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1],points[1:]], axis=1)

# Create the line collection object, setting the colormapping parameters.
# Have to set the actual values used for colormapping separately.
lc = LineCollection(segments, cmap=cmap, norm=norm, linewidth=2)

# Set color using signal values
lc.set_array(equity.signal.values)

fig, ax = plt.subplots()
fig.autofmt_xdate()

# Add collection to axes
ax.add_collection(lc)

plt.xlim(equity.index.min(), equity.index.max())
plt.ylim(equity.price.min(), equity.price.max())
plt.tight_layout()

# plt.savefig('test_mline.png', dpi=150)
plt.show()
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用