Pandas Dataframe 多彩线图

3 投票
1 回答
2661 浏览
提问于 2025-04-18 12:13

我有一个Pandas数据框,这个数据框的索引是日期时间,还有两列分别表示风速和环境温度。这里是半天的数据

                        temp        winds

2014-06-01 00:00:00     8.754545    0.263636
2014-06-01 01:00:00     8.025000    0.291667
2014-06-01 02:00:00     7.375000    0.391667
2014-06-01 03:00:00     6.850000    0.308333
2014-06-01 04:00:00     7.150000    0.258333
2014-06-01 05:00:00     7.708333    0.375000
2014-06-01 06:00:00     9.008333    0.391667
2014-06-01 07:00:00     10.858333   0.300000
2014-06-01 08:00:00     12.616667   0.341667
2014-06-01 09:00:00     15.008333   0.308333
2014-06-01 10:00:00     17.991667   0.491667
2014-06-01 11:00:00     21.108333   0.491667
2014-06-01 12:00:00     21.866667   0.395238

我想把这些数据画成一条线,线的颜色根据温度变化。例如,温度越高,颜色从浅红色变成深红色。

我找到一个关于用matplotlib绘制多种颜色线条的例子,但是我不知道怎么把它用在Pandas数据框上。有没有人知道我该怎么做?如果可以做到的话,能不能再加一个功能,让线的宽度根据风速变化?也就是说,风速越快,线就越宽。

谢谢大家的帮助!

1 个回答

5

pandas 里面的内置 plot 方法可能无法满足你的需求。你需要先提取数据,然后用 matplotlib 来绘图。

from matplotlib.collections import LineCollection
import matplotlib.dates as mpd

x=mpd.date2num(df.index.to_pydatetime())
y=df.winds.values
c=df['temp'].values
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, cmap=plt.get_cmap('copper'), norm=plt.Normalize(0, 10))
lc.set_array(c)
lc.set_linewidth(3)
ax=plt.gca()
ax.add_collection(lc)
plt.xlim(min(x), max(x))
ax.xaxis.set_major_locator(mpd.HourLocator())
ax.xaxis.set_major_formatter(mpd.DateFormatter('%Y-%m-%d:%H:%M:%S'))
_=plt.setp(ax.xaxis.get_majorticklabels(), rotation=70 )
plt.savefig('temp.png')

enter image description here

这里有两个值得注意的问题:

  • 颜色渐变的范围是通过 norm=plt.Normalize(0, 10) 来控制的。
  • pandasmatplotlib 在绘制时间序列时的方式不同,这就需要在绘图之前把 df.index 转换成 float 类型。而通过修改 major_locators,我们可以把 xaxis majorticklabels 变回日期时间格式。
  • 第二个问题可能会在我们想要绘制多条线的时候造成麻烦(因为数据会在两个不同的 x 范围内绘制):

    #follow what is already plotted:
    df['another']=np.random.random(13)
    print ax.get_xticks()
    df.another.plot(ax=ax, secondary_y=True)
    print ax.get_xticks(minor=True)
    
    [ 735385.          735385.04166667  735385.08333333  735385.125
      735385.16666667  735385.20833333  735385.25        735385.29166667
      735385.33333333  735385.375       735385.41666667  735385.45833333
      735385.5       ]
    [389328 389330 389332 389334 389336 389338 389340]
    

    因此,我们需要在不使用 pandas.plot() 方法的情况下来完成这项工作:

    ax.twinx().plot(x, df.another)
    

    enter image description here

    撰写回答