fig = plt.figure(figsize=(16, 12))
gs = gridspec.GridSpec(2, 2, hspace=0.35, wspace=0.3)
# Panel A: Disposable Gini bar chart
ax1 = fig.add_subplot(gs[0, 0])
if not gini_disp.empty:
latest = (gini_disp.sort_values('year', ascending=False)
.groupby('country_code').first().reset_index()
.sort_values('gini'))
colors = [country_color(c) for c in latest['country_code']]
ax1.barh([country_name(c) for c in latest['country_code']],
latest['gini'], color=colors, alpha=0.8)
ax1.set_xlabel('Gini coefficient')
ax1.set_title('A. Disposable Income Inequality', fontsize=12, fontweight='bold')
# Panel B: Pre-tax top 10% share time series
ax2 = fig.add_subplot(gs[0, 1])
ts_countries = ['US', 'FR', 'DE', 'SE', 'GB']
pretax_top10 = wid.get_top_shares_timeseries(
ts_countries, percentile='p90p100', concept='pretax', start_year=1980)
if not pretax_top10.empty:
for cc in ts_countries:
data = pretax_top10[pretax_top10['country'] == cc].sort_values('year')
if not data.empty:
ax2.plot(data['year'], data['value'],
color=country_color(cc), linewidth=2,
label=country_name(cc))
ax2.yaxis.set_major_formatter(mtick.PercentFormatter(1.0))
ax2.legend(fontsize=8)
ax2.set_title('B. Pre-Tax Top 10% Share (since 1980)', fontsize=12, fontweight='bold')
# Panel C: Redistribution — market vs disposable Gini
ax3 = fig.add_subplot(gs[1, 0])
redist = swiid.get_redistribution(summary_countries, start_year=2017, end_year=2022)
if not redist.empty:
latest_r = (redist.sort_values('year', ascending=False)
.groupby('country_code').first().reset_index())
latest_r = latest_r.dropna(subset=['gini_mkt', 'gini_disp'])
latest_r = latest_r[latest_r['country_code'] != ''].sort_values('gini_disp')
y_pos = np.arange(len(latest_r))
ax3.barh(y_pos, latest_r['gini_mkt'].values, 0.4,
label='Market Gini', color='#c75b5b', alpha=0.6)
ax3.barh(y_pos + 0.4, latest_r['gini_disp'].values, 0.4,
label='Disposable Gini', color='#4878a8', alpha=0.8)
ax3.set_yticks(y_pos + 0.2)
ax3.set_yticklabels([country_name(c) for c in latest_r['country_code']])
ax3.set_xlabel('Gini coefficient')
ax3.legend(fontsize=8)
ax3.set_title('C. Market vs. Disposable Inequality', fontsize=12, fontweight='bold')
# Panel D: Gini vs life expectancy
ax4 = fig.add_subplot(gs[1, 1])
spirit_data = health_social.get_spirit_level_data(year=2019)
if (not spirit_data.empty and 'gini_disp' in spirit_data.columns
and 'life_expectancy' in spirit_data.columns):
df = spirit_data.dropna(subset=['gini_disp', 'life_expectancy'])
colors = [country_color(c) if c in COUNTRY_NAMES else '#999'
for c in df['country_code']]
ax4.scatter(df['gini_disp'], df['life_expectancy'],
c=colors, s=80, zorder=5, edgecolors='white', linewidth=0.5)
annotate_countries(ax4, df['gini_disp'].values,
df['life_expectancy'].values,
df['country_code'].values)
ax4.set_xlabel('Gini (disposable)')
ax4.set_ylabel('Life expectancy')
ax4.set_title('D. Inequality vs. Life Expectancy', fontsize=12, fontweight='bold')
fig.suptitle('US-Europe Inequality: A Summary Dashboard', fontsize=16, fontweight='bold', y=1.01)
save_figure(fig, '06_synthesis_dashboard')
plt.show()