如何制作匹配时长、顶部为斜线的时间序列条形图
实现顶部为斜线的时间序列条形图
我需要在时间序列画布上展示条形图,要求:
- 条形宽度与对应时间段的时长匹配
- 条形顶部边缘连接该时间段的首个数据值与末尾数据值,也就是顶部为斜线以契合数据走势的黑色折线
我已经能实现基于末尾值(示例1)或首个值(示例2)的普通条形图,但需要的是贴合折线的多边形条形:
示例1:基于时间段末尾值绘制的条形图,顶部为水平边,无法贴合折线
示例2:基于时间段首个值绘制的条形图,顶部为水平边,无法贴合折线
解决方案
普通的plt.bar无法实现顶部斜线的效果,我们可以使用matplotlib.patches.Polygon手动绘制每个时间段的多边形区域。每个多边形的四个顶点为:(Start, 0)、(Start, First)、(End, Last)、(End, 0),连接这些点就能形成顶部带斜线的条形,完美贴合数据折线。
完整代码
import pandas as pd from pandas import Timestamp import matplotlib.pyplot as plt from matplotlib.patches import Polygon # 初始化数据 dd = {'Name': {0: 'A', 1: 'B', 2: 'C'}, 'Start': {0: Timestamp('1800-01-01 00:00:00'), 1: Timestamp('1850-01-01 00:00:00'), 2: Timestamp('1950-01-01 00:00:00')}, 'End': {0: Timestamp('1849-12-31 00:00:00'), 1: Timestamp('1949-12-31 00:00:00'), 2: Timestamp('1979-12-31 00:00:00')}, 'Team': {0: 'Red', 1: 'Blue', 2: 'Red'}, 'First': {0: 5, 1: 10, 2: 8}, 'Last': {0: 10, 1: 8, 2: 12}} d = pd.DataFrame.from_dict(dd) # 设置团队颜色 colors = {'Red': '#E81B23', 'Blue': '#00AEF3'} # 准备折线图数据 def reshape(data): d1 = data[['Start', 'First']].rename(columns={'Start': 'Date', 'First': 'value'}) d2 = data[['End', 'Last']].rename(columns={'End': 'Date', 'Last': 'value'}) return pd.concat([d1, d2]).sort_values(by='Date').reset_index(drop=True) df = reshape(d) # 创建画布 fig, ax = plt.subplots() # 绘制黑色折线 ax.plot(df['Date'], df['value'], color='black') # 遍历每个时间段,绘制多边形条形 for idx, row in d.iterrows(): # 定义多边形的四个顶点 vertices = [ (row['Start'], 0), (row['Start'], row['First']), (row['End'], row['Last']), (row['End'], 0) ] # 创建多边形并添加到坐标轴 poly = Polygon(vertices, color=colors[row['Team']], edgecolor='white', linewidth=2) ax.add_patch(poly) # 设置坐标轴范围,确保所有元素都显示 ax.set_xlim(df['Date'].min(), df['Date'].max()) ax.set_ylim(0, df['value'].max() + 2) plt.show()
效果说明
运行代码后,每个时间段的条形顶部会以斜线连接该时段的首尾数据值,完全贴合黑色折线的走势,同时条形宽度自动匹配时间段的时长,满足需求。
内容的提问来源于stack exchange,提问作者PatrickT
相关产品推荐
相关产品推荐

