I want to use axvspan() function to visualize a DataFrame that I obtained using Pandas DataReader.But when I use the the following codes, I saw an error and there is no shading in subplots. What should I do? Thank you.
JavaScript
x
37
37
1
import matplotlib.pyplot as plt
2
import pandas_datareader.data as pdr
3
import pandas as pd
4
import datetime
5
start = datetime.datetime (2000,1,1)
6
end = datetime.datetime (2021,5,1)
7
df = pdr.DataReader(['WFRBSB50215', 'WFRBST01134','WFRBST01122', 'WFRBSN09139', 'WFRBSB50189', 'WFRBST01110','WFRBSB50191'],'fred',start, end)
8
df.columns = ['Share of Total Net Worth Held by the Bottom 50% (1st to 50th Wealth Percentiles)',
9
'Share of Total Net Worth Held by the Top 1% (99th to 100th Wealth Percentiles)',
10
'Share of Corporate Equities and Mutual Fund Shares Helb By Top1%(99th to 100th Wealth Percentiles)',
11
'Share of Financial Assets Held by the 90th to 99th Wealth Percentiles',
12
'Share of Total Assets Held by the Bottom 50% (1st to 50th Wealth Percentiles)',
13
'Share of Real Estate Held by the Top 1% (99th to 100th Wealth Percentiles)',
14
'Share of Real Estate Held by the Bottom %50(1st to 50th Wealth Percentiles)'
15
]
16
ax = df.plot(subplots=True, layout=(7,1), figsize=(15,15), linewidth=3.5, colormap="summer")
17
ax.axvspan('2007-1-12', '2009-6-1', color='c', alpha=0.5)
18
ax.axvspan('2019-12-1', '2020-2-1',color= 'orange', alpha=0.5)
19
plt.xlabel('Date')
20
ax[0,].set_title('Share of Total Net Worth Held by the Bottom 50%')
21
ax[0,].set_ylabel('Percent of Aggregate')
22
ax[1,].set_title('Share of Total Net Worth Held by the Top 1%')
23
ax[1,].set_ylabel('Percent of Aggregate')
24
ax[2,].set_title('Share of Corporate Equities and Mutual Fund Shares Helb By Top 1%')
25
ax[2,].set_ylabel('Percent of Aggregate')
26
ax[3,].set_title('Share of Financial Assets Held by the 90th to 99th Wealth Percentiles')
27
ax[3,].set_ylabel('Percent of Aggregate')
28
ax[4,].set_title('Share of Total Assets Held by the Bottom 50% ')
29
ax[4,].set_ylabel('Percent of Aggregate')
30
ax[5,].set_title('Share of Real Estate Held by the Top 1%')
31
ax[5,].set_ylabel('Percent of Aggregate')
32
ax[6,].set_title('Share of Real Estate Held by the Bottom %50')
33
ax[6,].set_ylabel('Percent of Aggregate')
34
plt.tight_layout()
35
plt.style.use('seaborn-white')
36
plt.show()
37
Advertisement
Answer
Try looping over all Subplots and adding axvspan
to the specific AxesSubplot
instead:
JavaScript
1
12
12
1
axes = df.plot(subplots=True, layout=(7, 1), figsize=(15, 15), linewidth=3.5,
2
colormap="summer", ylabel='Percent of Aggregate', xlabel='Date')
3
4
for (ax,), col in zip(axes, df.columns):
5
ax.axvspan('2007-1-12', '2009-6-1', color='c', alpha=0.5)
6
ax.axvspan('2019-12-1', '2020-2-1', color='orange', alpha=0.5)
7
ax.set_title(col)
8
9
plt.tight_layout()
10
plt.style.use('seaborn-white')
11
plt.show()
12
Some slight code reduction using the ylabel
and xlabel
kwargs of plot
and also setting subplot titles from df.columns
instead of manually.
Adding legend for axvspan
. The simplest approach is to add a label to each axvspan
and make the legend at the end of each iteration:
JavaScript
1
16
16
1
axes = df.plot(subplots=True, layout=(7, 1), figsize=(15, 15), linewidth=3.5,
2
colormap="summer", ylabel='Percent of Aggregate', xlabel='Date',
3
legend=False)
4
5
for (ax,), col in zip(axes, df.columns):
6
ax.axvspan('2007-1-12', '2009-6-1', color='c', alpha=0.5,
7
label='2008 Crisis')
8
ax.axvspan('2019-12-1', '2020-2-1', color='orange', alpha=0.5,
9
label='Pandemic')
10
ax.set_title(col)
11
ax.legend()
12
13
plt.style.use('seaborn-white')
14
plt.tight_layout()
15
plt.show()
16
Alternatively a single legend can be made for just the Crises:
JavaScript
1
20
20
1
fig, axes = plt.subplots(nrows=7, figsize=(15, 15))
2
df.plot(subplots=True, ax=axes, linewidth=3.5,
3
colormap="summer", ylabel='Percent of Aggregate', xlabel='Date')
4
5
for ax, col in zip(axes, df.columns):
6
ax.axvspan('2007-1-12', '2009-6-1', color='c', alpha=0.5,
7
label='2008 Crisis')
8
ax.axvspan('2019-12-1', '2020-2-1', color='orange', alpha=0.5,
9
label='Pandemic')
10
ax.set_title(col)
11
12
handles, labels = axes[-1].get_legend_handles_labels()
13
14
fig.legend(handles[-2:], labels[-2:], title='Crises',
15
loc='lower left', ncol=2)
16
17
plt.style.use('seaborn-white')
18
plt.tight_layout()
19
plt.show()
20
^ Single legend is here in the lower left.