首页 > 解决方案 > 具有熊猫数据框绘图功能的颜色图

问题描述

我有来自多个站点的数据,这些数据记录了监控参数的急剧变化。我如何使用与值相关的颜色来绘制所有这些站点的数据以增强可视化效果?

import numpy as np
import pandas as pd
import string

# site names
cols = string.ascii_uppercase

# number of days
ndays = 3

# index
index = pd.date_range('2018-05-01', periods=3*24*60, freq='T')

# simulated daily data
d1 = np.random.randn(len(index)//ndays, len(cols))
d2 = np.random.randn(len(index)//ndays, len(cols))+2
d3 = np.random.randn(len(index)//ndays, len(cols))-2
data=np.concatenate([d1, d2, d3]) 

# df = pd.DataFrame(data=data, index=index, columns=list(cols))
df.plot(legend=False)

在上面的代码中,每个站点(列)都被分配了一种颜色。有没有办法将参数值表示为不同的颜色?

我想一种替代方法是使用散点图函数中的颜色图选项:如何使用颜色图为 Pandas DataFrames 着色图

ax = plt.subplots(figsize=(12,6))
collection = [plt.scatter(range(len(df)), df[col], c=df[col], s=25, cmap=cmap, edgecolor='None') for col in df.columns]

但是,如果我随着时间的推移(即x=df.index)绘制,事情似乎没有按预期工作。

还有其他选择吗?或建议如何更好地可视化时间序列的突然变化?

标签: pandasmatplotlibplotcolormap

解决方案


在下文中,我将只使用 3 列和每小时数据,以使绘图看起来不那么混乱。这些示例也适用于原始数据。

cols = string.ascii_uppercase[:3]
ndays = 3
index = pd.date_range('2018-05-01', periods=3*24, freq='H')

# simulated daily data
d1 = np.random.randn(len(index)//ndays, len(cols))
d2 = np.random.randn(len(index)//ndays, len(cols))+2
d3 = np.random.randn(len(index)//ndays, len(cols))-2
data=np.concatenate([d1, d2, d3]) 

df = pd.DataFrame(data=data, index=index, columns=list(cols))
df.plot(legend=False)

在此处输入图像描述

熊猫之路

你不走运,由于长期存在的错误DataFrame.plot.scatter,不适用于类似日期时间的数据。

matplotlib 方式

Matplotlibscatter可以处理类似日期时间的数据,但 x 轴没有按预期缩放。

for col in df.columns:
    plt.scatter(df.index, df[col], c=df[col])
plt.gcf().autofmt_xdate()

在此处输入图像描述

这对我来说似乎是一个错误,但我找不到任何报告。您可以通过手动调整 x 限制来解决此问题。

for col in df.columns:
    plt.scatter(df.index, df[col], c=df[col])

start, end = df.index[[0, -1]]
xmargin = (end - start) * plt.gca().margins()[0]
plt.xlim(start - xmargin, end + xmargin)
plt.gcf().autofmt_xdate()

在此处输入图像描述

不幸的是,x 轴格式化程序不如 pandas 好。

熊猫之路,重温

我偶然发现了这个技巧,但我不明白它为什么会起作用。如果您在调用 matplotlib 之前绘制由相同日期时间数据索引的 pandas 系列scatter,自动缩放问题就会消失,并且您会得到漂亮的 pandas 格式。

所以我制作了第一列的不可见图,然后是散点图。

df.iloc[:, 0].plot(lw=0)  # invisible plot
for col in df.columns:
    plt.scatter(df.index, df[col], c=df[col])

在此处输入图像描述


推荐阅读