Python 如何对两个折线图之间的区域进行着色

Python 如何对两个折线图之间的区域进行着色,python,pandas,matplotlib,data-science,Python,Pandas,Matplotlib,Data Science,我在两个线图之间的区域着色时遇到了一个问题,因为它们都有不同的日期值(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"

我在两个线图之间的区域着色时遇到了一个问题,因为它们都有不同的日期值(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 \N{DEGREE SIGN}C", 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()

假设两个系列都有相同的x值。如果起始值和结束值相同,则可以插值。但是,在您的示例中并非如此。 您可以改为创建路径对象并将其添加为填充面片:

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 \N{DEGREE SIGN}C", fontsize=16)
ax.set_title("Extreme Temperature Recorded Every Year")

ax.legend(loc='best')

plt.show()
样本输出:

假设两个系列都有相同的x值。如果起始值和结束值相同,则可以插值。但是,在您的示例中并非如此。 您可以改为创建路径对象并将其添加为填充面片:

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 \N{DEGREE SIGN}C", fontsize=16)
ax.set_title("Extreme Temperature Recorded Every Year")

ax.legend(loc='best')

plt.show()
样本输出:

与@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 \N{DEGREE SIGN}C", 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)
输出:

与@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 \N{DEGREE SIGN}C", 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)
输出:


啊,说得好。我不认为这可能是在曲线之间填充区域的预期输出。如果这个答案解决了你的问题,你。啊,好点。我不认为这可能是在曲线之间填充区域的预期输出。如果这个答案解决了你的问题,你。TypeError:FLUATE()参数必须是一个字符串或一个数字,而不是“时间戳”。我在声明'p'时遇到了这个错误,如果问题没有提供.TypeError:float()参数必须是字符串或数字,而不是'Timestamp'。我在声明“p”时发现了这个错误,如果问题没有提供答案,就会发生这种情况。