Python中基于条件的多色时间序列绘图

Python中基于条件的多色时间序列绘图,python,pandas,matplotlib,plot,time-series,Python,Pandas,Matplotlib,Plot,Time Series,我有一个pandas Financial timeseries数据框架,有两列和一个datetime索引 TOTAL.PAPRPNT.M Label 1973-03-01 25504.000 3 1973-04-01 25662.000 3 1973-05-01 25763.000 0 1973-06-01 25996.000 0 1973-07-01 2602

我有一个pandas Financial timeseries数据框架,有两列和一个datetime索引

            TOTAL.PAPRPNT.M  Label
1973-03-01        25504.000      3
1973-04-01        25662.000      3
1973-05-01        25763.000      0
1973-06-01        25996.000      0
1973-07-01        26023.000      1
1973-08-01        26005.000      1
1973-09-01        26037.000      2
1973-10-01        26124.000      2
1973-11-01        26193.000      3
1973-12-01        26383.000      3
正如您所见,每个数据集对应一个“标签”。如果从上一个“点”到下一个“点”的直线具有某些特征(不同类型的股票图变化),因此,对于这些图中的每一个,都应使用单独的颜色,则该标签基本上应进行分类。这个问题与这个问题相关,但“groupby”部分完全跳过了我的理解,这个方案是双色方案,而不是多色方案(我有四个标签)


我想根据与数据框中每个条目相关联的标签创建一个多色图

下面是一个我认为你在尝试做什么的例子。它基于评论中提到的MPL文档,并使用随机生成的数据。 只需将colormap边界映射到类数给定的离散值

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


num_classes = 4
ts = range(10)
df = pd.DataFrame(data={'TOTAL': np.random.rand(len(ts)), 'Label': np.random.randint(0, num_classes, len(ts))}, index=ts)
print(df)

cmap = ListedColormap(['r', 'g', 'b', 'y'])
norm = BoundaryNorm(range(num_classes+1), cmap.N)
points = np.array([df.index, df['TOTAL']]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

lc = LineCollection(segments, cmap=cmap, norm=norm)
lc.set_array(df['Label'])

fig1 = plt.figure()
plt.gca().add_collection(lc)
plt.xlim(df.index.min(), df.index.max())
plt.ylim(-1.1, 1.1)
plt.show()
每个线段根据
df['label']
中给出的类别标签上色,下面是一个示例结果:


以下是一个我认为你试图做的事情的例子。它基于评论中提到的MPL文档,并使用随机生成的数据。 只需将colormap边界映射到类数给定的离散值

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


num_classes = 4
ts = range(10)
df = pd.DataFrame(data={'TOTAL': np.random.rand(len(ts)), 'Label': np.random.randint(0, num_classes, len(ts))}, index=ts)
print(df)

cmap = ListedColormap(['r', 'g', 'b', 'y'])
norm = BoundaryNorm(range(num_classes+1), cmap.N)
points = np.array([df.index, df['TOTAL']]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

lc = LineCollection(segments, cmap=cmap, norm=norm)
lc.set_array(df['Label'])

fig1 = plt.figure()
plt.gca().add_collection(lc)
plt.xlim(df.index.min(), df.index.max())
plt.ylim(-1.1, 1.1)
plt.show()
每个线段根据
df['label']
中给出的类别标签上色,下面是一个示例结果:


您不需要groupby,您需要遵循MPL文档中的另一个问题:我也看到了,但我不知道如何将其与日期时间索引一起使用。这个特殊的pylab涉及使用linspace的数学函数。它只是在数据上使用布尔掩码/索引。您可以将其应用于数据帧中的任何列。如果您不想,则无需使用groupby。我建议您尝试使用LineCollection实现基于matplotlib示例的解决方案。显示此尝试的代码,并清楚说明出现问题的时间点。另外,看看哪些实际使用x轴上的日期。再次明确说明它在多大程度上没有帮助。您不需要groupby,您需要遵循MPL文档中的另一个问题:我也看到了,但我不明白如何将其与日期时间索引一起使用。这个特殊的pylab涉及使用linspace的数学函数。它只是在数据上使用布尔掩码/索引。您可以将其应用于数据帧中的任何列。如果您不想,则无需使用groupby。我建议您尝试使用LineCollection实现基于matplotlib示例的解决方案。显示此尝试的代码,并清楚说明出现问题的时间点。另外,看看哪些实际使用x轴上的日期。再次明确说明这在多大程度上没有帮助。非常感谢。上帝保佑你。成功了!虽然我必须使用'mdates.date2num'将索引更改为数字,因为在您的方案中,数据帧没有日期时间索引。@DanishAmjadAlvi不客气!很高兴我能帮忙。非常感谢。上帝保佑你。成功了!虽然我必须使用'mdates.date2num'将索引更改为数字,因为在您的方案中,数据帧没有日期时间索引。@DanishAmjadAlvi不客气!很高兴我能帮忙。