Reputation: 377
I am facing a problem in shading the region between the two line graphs as they both have different values of dates(x-axis).
Here is the code:
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()
Upvotes: 1
Views: 234
Reputation: 153510
Similiar to the "interpolating method" mentioned by @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)
Output:
Upvotes: 1
Reputation: 12410
fill_between
assumes you have common x-values for both series. If start and end values were the same, you could interpolate as implemented here. However, this is not the case in your example.
You could instead create a path object and add it as a filled patch:
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()
Upvotes: 2