如何对两个折线图之间的区域进行着色
Posted
技术标签:
【中文标题】如何对两个折线图之间的区域进行着色【英文标题】:How do I shade the region between the two line graph 【发布时间】:2021-05-13 09:59:30 【问题描述】:我在对两个折线图之间的区域进行着色时遇到问题,因为它们都有不同的日期值(x 轴)。
代码如下:
plt.figure(figsize=(30,20))
fig, ax = plt.subplots(1)
plt.plot(highs['Date'], highs['Data_Value'], label = "Record High")
plt.plot(lows['Date'], lows['Data_Value'], label = "Record Low")
plt.scatter(tmin2015['Date'].tolist(), tmin2015['Data_Value'], marker='o', c='green', label="2015 record low")
x = plt.gca().xaxis
plt.xlabel("Year", fontsize=16)
plt.ylabel("Temperature in \NDEGREE SIGNC", fontsize=16)
plt.title("Extreme Temperature Recorded Every Year")
for item in x.get_ticklabels():
item.set_rotation(45)
plt.legend(loc='best')
# ax.fill_between(highs['Date'],lows['Data_Value'], highs['Data_Value'])
plt.show()
【问题讨论】:
【参考方案1】:fill_between
假设您对两个系列都有共同的 x 值。如果开始值和结束值相同,则可以插入 as implemented here。但是,在您的示例中并非如此。
您可以改为创建一个路径对象并将其添加为填充补丁:
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.path import Path
from matplotlib.patches import PathPatch
fig, ax = plt.subplots(figsize=(15, 10))
#test data generation
highs = pd.DataFrame('Date': [1, 2, 4, 5], 'Data_Value': [17, 21, 18, 19])
lows = pd.DataFrame('Date': [0, 2, 3, 4], 'Data_Value': [1, 3, 2, 3])
#path object added as patch
p = Path(list(zip(lows['Date'], lows['Data_Value']))[::-1] + list(zip(highs['Date'], highs['Data_Value'])))
patch = PathPatch(p, facecolor="orange", lw=0, alpha=0.2, zorder=-1)
ax.add_patch(patch)
#line graphs plotted on top of the patch
ax.plot(highs['Date'], highs['Data_Value'], label = "Record High", lw=2)
ax.plot(lows['Date'], lows['Data_Value'], label = "Record Low", lw=2)
ax.set_xlabel("Year", fontsize=16)
ax.set_ylabel("Temperature in \NDEGREE SIGNC", fontsize=16)
ax.set_title("Extreme Temperature Recorded Every Year")
ax.legend(loc='best')
plt.show()
示例输出:
【讨论】:
TypeError: float() 参数必须是字符串或数字,而不是“时间戳”。我在声明“p”时遇到了这个错误 如果问题没有提供minimal, reproducible example,就会发生这种情况。【参考方案2】:类似于@MrT提到的“插值法”:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df_high = pd.DataFrame('Date':pd.date_range('2020-01-01', periods=100, freq='3D'),
'data_value':400+np.random.randint(0,20, 100))
df_low = pd.DataFrame('Date':pd.date_range('2020-03-03', periods=100, freq='3D'),
'data_value':-200+np.random.randint(0,20, 100))
plt.figure(figsize=(30,20))
fig, ax = plt.subplots(1)
plt.plot(df_high['Date'], df_high['data_value'], label = "Record High")
plt.plot(df_low['Date'], df_low['data_value'], label = "Record Low")
# plt.scatter(tmin2015['Date'].tolist(), tmin2015['Data_Value'], marker='o', c='green', label="2015 record low")
x = plt.gca().xaxis
plt.xlabel("Year", fontsize=16)
plt.ylabel("Temperature in \NDEGREE SIGNC", fontsize=16)
plt.title("Extreme Temperature Recorded Every Year")
for item in x.get_ticklabels():
item.set_rotation(45)
plt.legend(loc='best')
min_x = max(df_high['Date'].min(), df_low['Date'].min())
max_x = min(df_high['Date'].max(), df_low['Date'].max())
xrange = df_low.set_index('Date').index.union(df_high.set_index('Date').index)
lows = df_low.set_index('Date').reindex(xrange).interpolate().loc[min_x:max_x, 'data_value']
highs = df_high.set_index('Date').reindex(xrange).interpolate().loc[min_x:max_x, 'data_value']
ax.fill_between(lows.index, lows, highs, alpha=.4)
输出:
【讨论】:
啊,好点子。我不认为这可能是填充曲线之间区域的预期输出。 如果这个答案解决了你的问题,你should accept it。以上是关于如何对两个折线图之间的区域进行着色的主要内容,如果未能解决你的问题,请参考以下文章