def get_mc_directories(rfrac): rootdir = os.getcwd()+'/monte_carlo/' _dirs = []; _lbls = [] # for subdir, dirs, files in os.walk(rootdir): if subdir != rootdir and rfrac in subdir: _dirs.append(subdir) __sector = subdir.replace(rootdir+'relax_','').replace(rfrac,'') try: _lbls.append(monte_carlo(0,'base').sector_labels[__sector]) except: _lbls.append(__sector) return _dirs,_lbls
def plot_status_vs_valueadd(base_code,rfrac,fom_x,fom_y): mc = monte_carlo(0,'base') dirs,labels = get_mc_directories(rfrac) base_x = pd.read_csv('monte_carlo/{}/{}.csv'.format(base_code,fom_x),index_col=0).sum(axis=1) base_y = pd.read_csv('monte_carlo/{}/{}.csv'.format(base_code,fom_y),index_col=0).sum(axis=1) sf_x = 1 sf_y = 1 for _nd,_d in enumerate(dirs): _fx = pd.read_csv(_d+'/{}.csv'.format(fom_x),index_col=0) _fy = pd.read_csv(_d+'/{}.csv'.format(fom_y),index_col=0) x_val = sf_x*(base_x.mean()-_fx.sum(axis=1).mean()) y_val = sf_y*(base_y.mean()-_fy.sum(axis=1).mean()) x_err = 2*(base_x-_fx.sum(axis=1)).std()/np.sqrt(float(base_x.shape[0])) y_err = 2*(base_y-_fy.sum(axis=1)).std()/np.sqrt(float(base_y.shape[0])) if (x_val-x_err > 0 or y_val-y_err > 0): plt.errorbar(x_val,y_val,xerr=x_err,yerr=y_err,fmt='o',zorder=90,color=sns_pal[1],alpha=(0.7 if (x_val-x_err>0 and y_val-y_err>0) else 0.3)) plt.annotate(labels[_nd],xy=(x_val+x_err/10,y_val+y_err/10),fontsize=8,color=greys_pal[5],rotation=0,ha='left',va='bottom',weight=500) plt.xlim(0) plt.ylim(0) plt.annotate('{}% recovery of\nsectoral activity'.format(rfrac),xy=(0.05,0.95), xycoords='axes fraction',ha='left',va='top',fontsize=8,color=greys_pal[6],annotation_clip=False) plt.grid(False) sns.despine(bottom=True,left=True) plt.plot([0,0],plt.gca().get_ylim(),color=greys_pal[6],zorder=10) plt.plot(plt.gca().get_xlim(),[0,0],color=greys_pal[6],zorder=10) plt.xlabel(ax_label_dict[fom_x],labelpad=10,linespacing=1.75) plt.ylabel(ax_label_dict[fom_y],labelpad=10,linespacing=1.75) # save & close plt.savefig('figs/scatter_{}_{}.pdf'.format(fom_x,fom_y),format='pdf',bbox_inches='tight') plt.close('all')
def explore_poverty_mysteries(hh_df, scaleup_CCT=0, mirror_subsistence=False): mc = monte_carlo(0, 'base') ul = 250 nbins = int(50) # total income <-- use to structure plot tot_hgt, _bins = np.histogram(hh_df.eval('pcinc_initial').clip(upper=ul), bins=nbins, weights=hh_df['popwgt']) wid = (_bins[1] - _bins[0]) bin_slice = '(pcinc_initial>@b)&(pcinc_initial<=@_bins[@n+1])' # households falling into poverty newpov = '&(@mc.m2d*pcinc_initial>3.20)&(@mc.m2d*pcinc_final<=3.20)' month1 = '&(@mc.m2d*(hhinc-income_loss+savings/1+cct4P*@scaleup_CCT)/hhsize<=3.20)' month2 = '&(@mc.m2d*(hhinc-income_loss+savings/1+cct4P*@scaleup_CCT)/hhsize>3.20)&(@mc.m2d*(hhinc-income_loss+savings/2+cct4P*@scaleup_CCT)/hhsize<=3.20)' month3 = '&(@mc.m2d*(hhinc-income_loss+savings/2+cct4P*@scaleup_CCT)/hhsize>3.20)&(@mc.m2d*(hhinc-income_loss+savings/3+cct4P*@scaleup_CCT)/hhsize<=3.20)' month4 = '&(@mc.m2d*(hhinc-income_loss+savings/3+cct4P*@scaleup_CCT)/hhsize>3.20)' # households falling into extreme poverty newsub = '&(@mc.m2d*pcinc_initial>1.90)&(@mc.m2d*pcinc_final<=1.90)' month1s = '&(@mc.m2d*(hhinc-income_loss+savings/1+cct4P*@scaleup_CCT)/hhsize<=1.90)' month2s = '&(@mc.m2d*(hhinc-income_loss+savings/1+cct4P*@scaleup_CCT)/hhsize>1.90)&(@mc.m2d*(hhinc-income_loss+savings/2+cct4P*@scaleup_CCT)/hhsize<=1.90)' month3s = '&(@mc.m2d*(hhinc-income_loss+savings/2+cct4P*@scaleup_CCT)/hhsize>1.90)&(@mc.m2d*(hhinc-income_loss+savings/3+cct4P*@scaleup_CCT)/hhsize<=1.90)' month4s = '&(@mc.m2d*(hhinc-income_loss+savings/3+cct4P*@scaleup_CCT)/hhsize>1.90)' newpov_hgt = [] newpov_1m_hgt = [] newpov_2m_hgt = [] newpov_3m_hgt = [] newpov_4m_hgt = [] newsub_hgt = [] newsub_1m_hgt = [] newsub_2m_hgt = [] newsub_3m_hgt = [] newsub_4m_hgt = [] for n, b in enumerate(_bins[:-1]): newpov_hgt.append(hh_df.loc[hh_df.eval(bin_slice + newpov), 'popwgt'].sum()) newpov_1m_hgt.append(hh_df.loc[hh_df.eval(bin_slice + newpov + month1), 'popwgt'].sum()) newpov_2m_hgt.append(hh_df.loc[hh_df.eval(bin_slice + newpov + month2), 'popwgt'].sum()) newpov_3m_hgt.append(hh_df.loc[hh_df.eval(bin_slice + newpov + month3), 'popwgt'].sum()) newpov_4m_hgt.append(hh_df.loc[hh_df.eval(bin_slice + newpov + month4), 'popwgt'].sum()) # newsub_1m_hgt.append( -1 * hh_df.loc[hh_df.eval(bin_slice + newsub + month1s), 'popwgt'].sum()) newsub_2m_hgt.append( -1 * hh_df.loc[hh_df.eval(bin_slice + newsub + month2s), 'popwgt'].sum()) newsub_3m_hgt.append( -1 * hh_df.loc[hh_df.eval(bin_slice + newsub + month3s), 'popwgt'].sum()) newsub_4m_hgt.append( -1 * hh_df.loc[hh_df.eval(bin_slice + newsub + month4s), 'popwgt'].sum()) # # plot them #ax = plt.step(_bins[:-1]+wid,newpov_hgt,linewidth=0.5,alpha=0.4) btm = 0 lbl = '< 1 month ({} m.)'.format(round(np.sum(newpov_1m_hgt), 1)) ax = plt.bar(_bins[:-1], newpov_1m_hgt, bottom=btm, width=wid, align='edge', linewidth=0, alpha=0.5, facecolor=reds_pal[0], label=lbl) btm = newpov_1m_hgt lbl = '1-2 months ({} m.)'.format(round(np.sum(newpov_2m_hgt), 1)) ax = plt.bar(_bins[:-1], newpov_2m_hgt, width=wid, bottom=btm, align='edge', linewidth=0, alpha=0.5, facecolor=reds_pal[1], label=lbl) btm = [i + j for i, j in zip(newpov_1m_hgt, newpov_2m_hgt)] lbl = '2-3 months ({} m.)'.format(round(np.sum(newpov_3m_hgt), 1)) ax = plt.bar(_bins[:-1], newpov_3m_hgt, width=wid, bottom=btm, align='edge', linewidth=0, alpha=0.5, facecolor=reds_pal[2], label=lbl) btm = [ i + j + k for i, j, k in zip(newpov_1m_hgt, newpov_2m_hgt, newpov_3m_hgt) ] lbl = '> 3 months ({} m.)'.format(round(np.sum(newpov_4m_hgt), 1)) ax = plt.bar(_bins[:-1], newpov_4m_hgt, width=wid, bottom=btm, align='edge', linewidth=0, alpha=0.5, facecolor=reds_pal[3], label=lbl) # plot hh falling into subsistence if mirror_subsistence: btm = 0 lbl = '< 1 month ({} m.)'.format(round(-1 * np.sum(newsub_1m_hgt), 1)) ax = plt.bar(_bins[:-1], newsub_1m_hgt, bottom=btm, width=wid, align='edge', linewidth=0, alpha=0.35, facecolor=reds_pal[0], label=lbl) btm = newsub_1m_hgt lbl = '1-2 months ({} m.)'.format(-1 * round(np.sum(newsub_2m_hgt), 1)) ax = plt.bar(_bins[:-1], newsub_2m_hgt, width=wid, bottom=btm, align='edge', linewidth=0, alpha=0.35, facecolor=reds_pal[1], label=lbl) btm = [i + j for i, j in zip(newsub_1m_hgt, newsub_2m_hgt)] lbl = '2-3 months ({} m.)'.format(-1 * round(np.sum(newsub_3m_hgt), 1)) ax = plt.bar(_bins[:-1], newsub_3m_hgt, width=wid, bottom=btm, align='edge', linewidth=0, alpha=0.35, facecolor=reds_pal[2], label=lbl) btm = [ i + j + k for i, j, k in zip(newsub_1m_hgt, newsub_2m_hgt, newsub_3m_hgt) ] lbl = '> 3 months ({} m.)'.format(-1 * round(np.sum(newsub_4m_hgt), 1)) ax = plt.bar(_bins[:-1], newsub_4m_hgt, width=wid, bottom=btm, align='edge', linewidth=0, alpha=0.35, facecolor=reds_pal[3], label=lbl) # plt.legend(title='Shock duration{}'.format('\n({}% CCT scaleup)'.format( int(1E2 * scaleup_CCT)) if scaleup_CCT != 0 else ''), labelspacing=0.75, ncol=1, fontsize=8, borderpad=0.75, fancybox=True, frameon=True, framealpha=0.9) plt.xlabel('pre-COVID income [PPP$/cap/month]', labelpad=10) plt.ylabel('Impoverished population [millions]', labelpad=10) if not mirror_subsistence: plt.xlim(90, ul) else: plt.xlim(0, ul) plt.grid(False) sns.despine(left=True, bottom=True) plt.plot([0, ul], [0, 0], color=greys_pal[4], lw=1) plt.savefig('figs/new_poverty{}{}.pdf'.format( '_net_sub' if mirror_subsistence else '', '_CCT{}x'.format(scaleup_CCT) if scaleup_CCT != 0 else ''), format='pdf', bbox_inches='tight') plt.close('all')
def plot_income_scatter(hh_df, _ul=20, with_migration=True): mc = monte_carlo(0, 'base') nbins = 11 dy = 11 plt.scatter(mc.m2d * hh_df.loc[hh_df.income_loss != 0, 'pcinc_initial'], mc.m2d * hh_df.loc[hh_df.income_loss != 0, 'pcinc_final'], s=6, alpha=0.4) base_hgt, _bins = np.histogram( (mc.m2d * hh_df['pcinc_initial']).clip(upper=_ul), bins=[2 * n for n in range(0, 11)], weights=hh_df['popwgt']) shock_hgt, _ = np.histogram( (mc.m2d * hh_df['pcinc_final']).clip(upper=_ul), bins=_bins, weights=hh_df['popwgt']) wid = (_bins[1] - _bins[0]) for n, b in enumerate(_bins): plt.plot([b, b], [0, _ul], lw=0.6, color=greys_pal[5], ls=':', zorder=100) try: plt.annotate(r'$\Delta$P' + ': {}%'.format( int(round(1E2 * (shock_hgt[n] - base_hgt[n]) / base_hgt[n], 0))), xy=(b + wid / 2, np.e**(np.log(dy) / _ul * (b + wid / 2)) + _ul / 2 + 1), color=greys_pal[7], fontsize=5.5, ha='center', va='bottom', annotation_clip=False) except: pass try: bin_slice = '(@mc.m2d*pcinc_initial>@b)&(@mc.m2d*pcinc_initial<=@_bins[@n+1])' i_i = mc.m2d * hh_df.loc[ hh_df.eval(bin_slice), ['popwgt', 'pcinc_initial']].prod( axis=1).sum() / hh_df.loc[hh_df.eval(bin_slice), 'popwgt'].sum() if with_migration: bin_slice = '(@mc.m2d*pcinc_final>@b)&(@mc.m2d*pcinc_final<=@_bins[@n+1])' else: bin_slice = '(@mc.m2d*pcinc_initial>@b)&(@mc.m2d*pcinc_initial<=@_bins[@n+1])' i_f = mc.m2d * hh_df.loc[ hh_df.eval(bin_slice), ['popwgt', 'pcinc_final']].prod( axis=1).sum() / hh_df.loc[hh_df.eval(bin_slice), 'popwgt'].sum() di = round(1E2 * (i_f - i_i) / i_i, 1) plt.annotate(r'$\Delta$i' + ': {}%'.format(di), xy=(b + wid / 2, np.e**(np.log(dy) / _ul * (b + wid / 2)) + _ul / 2 + 0.2), color=greys_pal[7], fontsize=5.5, ha='center', va='bottom', annotation_clip=False) if n < 5: if n == 0: plt.annotate('poverty gap', style='italic', xy=(b + wid / 2, np.e**(np.log(dy) / _ul * (b + wid / 2)) + _ul / 2 - 1), color=greys_pal[7], fontsize=5.5, ha='center', va='bottom') pgap_i = round(1E2 * (i_i - 3.2) / 3.2, 1) plt.annotate(r'initial:' + '\n{}%'.format(pgap_i), xy=(b + wid / 20, np.e**(np.log(dy) / _ul * (b + wid / 2)) + _ul / 2 - 2.2), color=greys_pal[7], fontsize=5.5, ha='left', va='bottom', annotation_clip=False) pgap_f = round(1E2 * (i_f - 3.2) / 3.2, 1) plt.annotate(r'final:' + '\n{}%'.format(pgap_f), xy=(b + wid * 19 / 20, np.e**(np.log(dy) / _ul * (b + wid / 2)) + _ul / 2 - 3.4), color=greys_pal[7], fontsize=5.5, ha='right', va='bottom', annotation_clip=False) #pgap_i = None except: pass plt.xlabel('Income [PPP$/cap/day]', labelpad=10) plt.ylabel('Income during shock [PPP$/cap/day]', labelpad=10) plt.xlim(0, _ul) plt.ylim(0, _ul) plt.xticks([2 * n for n in range(0, 11)]) sns.despine() plt.savefig('figs/income_scatter_{}.pdf'.format( 'with_bin_migrants' if with_migration else 'no_bin_migrants'), format='pdf', bbox_inches='tight') plt.close('all')
def build_shock(fom='totpop_pov'): pal = monte_carlo().ichan_cols # create plot showing how impact channels add to affected, poverty initial = pd.read_csv('monte_carlo/inital_pop_by_class.csv'.format(fom)) base = pd.read_csv('monte_carlo/base/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) W1E0R0 = pd.read_csv('monte_carlo/W1E0R0/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) W0E1R0 = pd.read_csv('monte_carlo/W0E1R0/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) W0E0R1 = pd.read_csv('monte_carlo/W0E0R1/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) W1E1R0 = pd.read_csv('monte_carlo/W1E1R0/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) W0E1R1 = pd.read_csv('monte_carlo/W0E1R1/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) W1E0R1 = pd.read_csv('monte_carlo/W1E0R1/{}.csv'.format(fom), index_col=0)[['vul', 'sec', 'mc']].sum(axis=1) wid = 0.8 alp = 0.6 lw = 0.0 plt.barh(7, W0E0R1.mean(), facecolor=pal['remits'], lw=lw, height=wid, alpha=alp) plt.annotate(' {} mil.'.format(round(W0E0R1.mean(), 1)), xy=(W0E0R1.mean(), 7 + wid / 2), va='center', ha='left', color=greys_pal[6]) plt.barh(6, W0E1R0.mean(), facecolor=pal['entrep'], lw=lw, height=wid, alpha=alp) plt.annotate(' {} mil.'.format(round(W0E1R0.mean(), 1)), xy=(W0E1R0.mean(), 6 + wid / 2), va='center', ha='left', color=greys_pal[6]) plt.barh(5, W1E0R0.mean(), facecolor=pal['nonag_wage'], lw=lw, height=wid, alpha=alp) plt.annotate(' {} mil.'.format(round(W1E0R0.mean(), 1)), xy=(W1E0R0.mean(), 5 + wid / 2), va='center', ha='left', color=greys_pal[6]) # plt.barh(3, W0E1R1.mean(), facecolor=pal['entrep'], lw=lw, height=wid * 2 / 3, alpha=alp) plt.barh(3 + wid / 3, W0E1R1.mean(), facecolor=pal['remits'], lw=lw, height=wid * 2 / 3, alpha=alp) plt.annotate(' {} mil.'.format(round(W0E1R1.mean(), 1)), xy=(W0E1R1.mean(), 3 + wid / 2), va='center', ha='left', color=greys_pal[6]) plt.barh(2, W1E0R1.mean(), facecolor=pal['nonag_wage'], lw=lw, height=wid * 2 / 3, alpha=alp) plt.barh(2 + wid / 3, W1E0R1.mean(), facecolor=pal['remits'], lw=lw, height=wid * 2 / 3, alpha=alp) plt.annotate(' {} mil.'.format(round(W1E0R1.mean(), 1)), xy=(W1E0R1.mean(), 2 + wid / 2), va='center', ha='left', color=greys_pal[6]) plt.barh(1, W1E1R0.mean(), facecolor=pal['nonag_wage'], lw=lw, height=wid * 2 / 3, alpha=alp) plt.barh(1 + wid / 3, W1E1R0.mean(), facecolor=pal['entrep'], lw=lw, height=wid * 2 / 3, alpha=alp) plt.annotate(' {} mil.'.format(round(W1E1R0.mean(), 1)), xy=(W1E1R0.mean(), 1 + wid / 2), va='center', ha='left', color=greys_pal[6]) # plt.bar(9,base.mean(),facecolor=pal['remits'],lw=lw,width=wid/3,alpha=alp) # plt.bar(9+wid/3,base.mean(),facecolor=pal['entrep'],lw=lw,width=wid/3,alpha=alp) # plt.bar(9+wid*2/3,base.mean(),facecolor=pal['nonag_wage'],lw=lw,width=wid/3,alpha=alp) plt.barh([1, 2, 3, 5, 6, 7], 6 * [base.mean()], facecolor="None", lw=1, height=wid, edgecolor=greys_pal[7], alpha=0.3) plt.grid(True, axis='x', alpha=0.3) # plt.legend(loc='upper left',labelspacing=0.75,ncol=1,fontsize=8,borderpad=0.75,fancybox=True,frameon=True,framealpha=0.9) plt.yticks([_ + wid / 2 for _ in range(1, 8)], [ 'wages &\nentrepreneurial', 'wages &\nremittances', 'entrepreneurial &\n remittances', '', 'wage\neffect', 'entrepreneurial\neffect', 'remittance\neffect' ], va='center', ha='right') plt.xlabel('Poverty increase [mil.]', labelpad=10) plt.ylim(0.75, 8.05) sns.despine() plt.savefig('figs/build_a_crisis.pdf', format='pdf', bbox_inches='tight') plt.close('all')
def plot_income_hist(hh_df, shock_code='base', use_expenditures=False): mc = monte_carlo(0, 'base') ############################################### # function can plot income or expenditures # --> based on flag use_expenditures above _fom = 'inc' _label = 'Income' if use_expenditures: _fom = 'exp' _label = 'Expenditures' # use central value of MC series ts = load_consumption_time_series(shock_code) classes = { 'sub': [ts[0].T, -1E9, 1.9], 'pov': [ts[1].T, 1.9, 3.2], 'vul': [ts[2].T, 3.2, 5.5], 'sec': [ts[3].T, 5.5, 15.], 'mc': [ts[4].T, 15., 1E9] } ############################################### # upper limit, binning of histogram _ul = 20 nbins = int(50) # Income dist before disaster ci_hgt, _bins = np.histogram( (mc.m2d * hh_df['pc' + _fom + '_initial']).clip(upper=_ul), bins=nbins, weights=hh_df['popwgt']) wid = (_bins[1] - _bins[0]) / 2 # Income dist after disaster cf_hgt, _ = np.histogram( (mc.m2d * hh_df['pc' + _fom + '_final']).clip(upper=_ul), bins=_bins, weights=hh_df['popwgt']) # plot them ax = plt.bar(_bins[:-1], ci_hgt, width=wid, align='edge', linewidth=0, alpha=0.4, facecolor=cool_pal[5], label='2015 FIES') ax = plt.bar(_bins[:-1] - wid, cf_hgt, width=wid, align='edge', linewidth=0, alpha=0.4, facecolor=cool_pal[0], label='COVID shock') # annotate shifts pop_aff, frac_aff, tot_loss, di_tot, di_aff, affpop_sub, affpop_pov, affpop_vul = load_income_impacts( shock_code) _y = 0.0 _dy = {'sub': 9.2, 'pov': 7.8, 'vul': 6.3, 'sec': 3.7, 'mc': 0.5} lbl = { 'sub': 'extreme poverty', 'pov': 'poverty', 'vul': 'vulnerable', 'sec': 'secure', 'mc': 'middle class' } for _c in ['sub', 'pov', 'vul', 'sec', 'mc']: _mc, _min, _max = classes[_c] # segment plot # if _c != 'sub': plt.plot([max(0.05, _min), max(0.05, _min)], [0, _dy[_c] + 1.0], color=greys_pal[6], lw=1.4, ls='-', clip_on=False) plt.plot([max(0.05, _min), max(0.05, _min) + 0.1], [_dy[_c] + 1.0, _dy[_c] + 1.10], color=greys_pal[6], lw=1.4, ls='-', clip_on=False) # annotate population shifts # This loads population values from MC (consumption series) if not use_expenditures: print( '\n\nusing consumption (net sav), month = 12 for income hist') tot_pop = hh_df['popwgt'].sum() popi = round(1E-2 * tot_pop * _mc[0].mean(), 1) popf = round(1E-2 * tot_pop * _mc[12].mean(), 1) popf_min = round(1E-2 * tot_pop * _mc[12].quantile(0.25), 1) # popf-pop_err popf_max = round(1E-2 * tot_pop * _mc[12].quantile(0.75), 1) # popf+pop_err # get delta dp = round(popf - popi, 1) dp_max = round(popf_max - popi, 1) dp_min = round(popf_min - popi, 1) # pop frac affected frac_aff_min = int(round(frac_aff[_c].quantile(0.25))) frac_aff_max = int(round(frac_aff[_c].quantile(0.75))) if frac_aff_min != frac_aff_max: _anno = r'{}% $\endash$ {}%'.format(frac_aff_min, frac_aff_max) else: _anno = r'{}%'.format(int(round(frac_aff[_c].mean()))) _anno += ' of {} m. affected'.format(popi) + '\n' _anno += 'final pop: {} $\endash$ {} m.\n'.format(popf_min, popf_max) _anno += 'net shift: {}{} $\endash$ {}{} m.'.format( '+' if dp_min > 0 else '', dp_min, '+' if dp_max > 0 else '', dp_max) # income loss among affected # pcinc_init = mc.m2d*(hh_df.loc[hh_df['initial_class']==_c,['pcinc_initial','popwgt']].prod(axis=1).sum() # /hh_df.loc[hh_df['initial_class']==_c,'popwgt'].sum()) # di_aff_min = round(mc.m2d*di_aff[_c].quantile(0.25),1) # di_aff_max = round(mc.m2d*di_aff[_c].quantile(0.75),1) # if di_aff_min == di_aff_max : # _anno += r'\${}0{}'.format(round(mc.m2d*di_aff[_c].mean(),1),'/cap/day') # _anno += r' ({}%)'.format(int(1E2*mc.m2d*di_aff[_c].mean()/pcinc_init))+'lost \n' # else: # _anno += r'\${}0 $\endash$ \${}0{}'.format(di_aff_min,di_aff_max,'/cap/day') # _anno += r' ({}% $\endash$ {}%)'.format(int(1E2*di_aff_min/pcinc_init),int(1E2*di_aff_max/pcinc_init))+' lost\n' # if use_expenditures: plt.annotate(lbl[_c], xy=(max(0, _min) + 0.3, _y + _dy[_c] + 1.05), ha='left', va='bottom', fontsize=8, color=greys_pal[7], annotation_clip=False, weight='bold') plt.annotate(_anno, xy=(max(0, _min) + .55, _y + _dy[_c] + 0.94), ha='left', va='top', fontsize=8, color=greys_pal[7], annotation_clip=False, linespacing=1.5) plt.xlabel(_label + ' [PPP$/cap/day]', labelpad=10) plt.ylabel('Population [millions]', labelpad=10) plt.xlim(0) plt.ylim(0, 8.5) plt.yticks([n for n in range(1, 9)]) plt.grid(False) plt.legend(labelspacing=0.75, ncol=1, fontsize=8, borderpad=0.75, fancybox=True, frameon=True, framealpha=0.9) sns.despine(left=True) plt.savefig('figs/{}_hist.pdf'.format(_label.lower()), format='pdf', bbox_inches='tight') plt.close('all')
def plot_income_loss_by_channel(scode): pal = monte_carlo(0, 'base').ichan_cols _w = 0.75 _fs = 8 #flag fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 5)) plt.axes(ax[0]) rel = 'loss' # 'lossfrac' returns fraction *of each channel* agwage = pd.read_csv('monte_carlo/{}/ag_wage_{}.csv'.format(scode, rel), index_col=0) nagwage = pd.read_csv('monte_carlo/{}/nonag_wage_{}.csv'.format( scode, rel), index_col=0) remits = pd.read_csv('monte_carlo/{}/remits_{}.csv'.format(scode, rel), index_col=0) entrep = pd.read_csv('monte_carlo/{}/entrep_{}.csv'.format(scode, rel), index_col=0) # tot_loss = pd.read_csv('monte_carlo/{}/tot_loss.csv'.format(scode), index_col=0) # load initial income [mil. PPP/month] init_inc_aff = pd.read_csv( 'monte_carlo/{}/tot_inc_initial_affected.csv'.format(scode), index_col=0) # load affected population aff_pop = pd.read_csv('monte_carlo/{}/pop_aff.csv'.format(scode), index_col=0) # load total population # plot losses in PPP/cap btm = [0 for _ in agwage.columns] for ncl, cl in enumerate(['sub', 'pov', 'vul', 'sec', 'mc']): plt.bar(ncl, nagwage[cl].mean() / aff_pop[cl].mean(), bottom=btm[ncl], color=pal['nonag_wage'], width=_w, alpha=0.6, linewidth=0, label=('wages (non-ag)' if ncl == 0 else '')) btm[ncl] += nagwage[cl].mean() / aff_pop[cl].mean() plt.bar(ncl, entrep[cl].mean() / aff_pop[cl].mean(), bottom=btm[ncl], color=pal['entrep'], width=_w, alpha=0.6, linewidth=0, label=('entrepreneurial' if ncl == 0 else '')) btm[ncl] += entrep[cl].mean() / aff_pop[cl].mean() plt.bar(ncl, remits[cl].mean() / aff_pop[cl].mean(), bottom=btm[ncl], color=pal['remits'], width=_w, alpha=0.6, linewidth=0, label=('intl. remittances' if ncl == 0 else '')) btm[ncl] += remits[cl].mean() / aff_pop[cl].mean() plt.bar(ncl, agwage[cl].mean() / aff_pop[cl].mean(), bottom=btm[ncl], color=pal['ag_wage'], width=_w, alpha=0.6, linewidth=0, label=('agricultural wages' if ncl == 0 else '')) btm[ncl] += agwage[cl].mean() / aff_pop[cl].mean() # annotate with range _low = int(round(tot_loss[cl].quantile(0.25) / aff_pop[cl].mean())) _high = int(round(tot_loss[cl].quantile(0.75) / aff_pop[cl].mean())) plt.annotate('\${}$\endash${}'.format(_low, _high), xy=(_w / 2 + ncl, btm[ncl]), fontsize=_fs, color=greys_pal[7], ha='center', va='bottom') plt.xticks([_w / 2 + _ for _ in range(0, 5)], [ 'extreme\npoverty', 'poverty', 'vulnerable', 'secure', 'middle\nclass' ], fontsize=_fs, rotation=0) plt.xlim(-0.1, 4 + _w + 0.1) plt.yticks([_ * 50 for _ in range(0, 6)], fontsize=_fs) plt.ylabel('Value [PPP$/cap/month]', labelpad=10, linespacing=1.75, fontsize=_fs) plt.legend(loc='upper left', labelspacing=0.75, ncol=1, fontsize=_fs, borderpad=0.75, fancybox=True, frameon=True, framealpha=0.9) plt.grid(False) plt.grid(True, axis='y', alpha=0.4) sns.despine(left=True) # plt.savefig('figs/income_{}_by_channel.pdf'.format(rel),format='pdf',bbox_inches='tight') # plt.close('all') # plot fractional losses plt.axes(ax[1]) btm = [0 for _ in agwage.columns] for ncl, cl in enumerate(['sub', 'pov', 'vul', 'sec', 'mc']): plt.bar(ncl, 1E2 * nagwage[cl].mean() / init_inc_aff[cl].mean(), bottom=btm[ncl], color=pal['nonag_wage'], width=_w, alpha=0.6, linewidth=0, label=('non-ag wages' if ncl == 0 else '')) btm[ncl] += 1E2 * nagwage[cl].mean() / init_inc_aff[cl].mean() plt.bar(ncl, 1E2 * entrep[cl].mean() / init_inc_aff[cl].mean(), bottom=btm[ncl], color=pal['entrep'], width=_w, alpha=0.6, linewidth=0, label=('entrepreneurial income' if ncl == 0 else '')) btm[ncl] += 1E2 * entrep[cl].mean() / init_inc_aff[cl].mean() plt.bar(ncl, 1E2 * remits[cl].mean() / init_inc_aff[cl].mean(), bottom=btm[ncl], color=pal['remits'], width=_w, alpha=0.6, linewidth=0, label=('remittances' if ncl == 0 else '')) btm[ncl] += 1E2 * remits[cl].mean() / init_inc_aff[cl].mean() plt.bar(ncl, 1E2 * agwage[cl].mean() / init_inc_aff[cl].mean(), bottom=btm[ncl], color=pal['ag_wage'], width=_w, alpha=0.6, linewidth=0, label=('ag wages' if ncl == 0 else '')) btm[ncl] += 1E2 * agwage[cl].mean() / init_inc_aff[cl].mean() # annotate with range _low = int( round(1E2 * tot_loss[cl].quantile(0.25) / init_inc_aff[cl].mean())) _high = int( round(1E2 * tot_loss[cl].quantile(0.75) / init_inc_aff[cl].mean())) plt.annotate('{}$\endash${}%'.format(_low, _high), xy=(_w / 2 + ncl, btm[ncl]), fontsize=_fs, color=greys_pal[7], ha='center', va='bottom') plt.xticks([_w / 2 + _ for _ in range(0, 5)], [ 'extreme\npoverty', 'poverty', 'vulnerable', 'secure', 'middle\nclass' ], fontsize=_fs, rotation=0) plt.xlim(-0.1, 4 + _w + 0.1) plt.yticks([_ * 10 for _ in range(0, 5)], fontsize=_fs) plt.ylabel('Percentage of total income [%]', labelpad=10, linespacing=1.5, fontsize=_fs) #plt.legend(loc='upper left',labelspacing=0.75,ncol=1,fontsize=8,borderpad=0.75,fancybox=True,frameon=True,framealpha=0.9) plt.grid(False) plt.grid(True, axis='y', alpha=0.4) #plt.grid(True,axis='y') sns.despine(left=True) plt.savefig('figs/income_loss_by_channel.pdf'.format(rel), format='pdf', bbox_inches='tight') plt.close('all')
def plot_regional_poverty(scode): mc = monte_carlo(0, 'base') pov_init = pd.read_csv('monte_carlo/regional_poverty.csv', index_col=0, dtype='float', header=None).fillna(0) pov_init.columns = ['init'] pov_init.index = pov_init.index.astype('int') # pov_covid = pd.read_csv( 'monte_carlo/{}/regional_pov_covid.csv'.format(scode), index_col=0, dtype='float').mean(axis=0).T.to_frame(name='covid') pov_covid.index = pov_covid.index.astype('int') # pov_ESP = pd.read_csv( 'monte_carlo/{}/regional_pov_ESP_eligerr50.csv'.format(scode), index_col=0, dtype='float').mean(axis=0).T.to_frame(name='ESP') pov_ESP.index = pov_ESP.index.astype('int') # pov = pd.concat([pov_init, pov_covid, pov_ESP], axis=1) pov.index.name = 'region' pov = pov.reset_index() prov_code, reg_code = get_places_dict('PH') pov['region'].replace(reg_code, inplace=True) pov = pov.reset_index(drop=True).set_index('region') pov = pov.sort_values(by='ESP', ascending=True) pov.to_csv('csv/regional_poverty.csv') for _n, _ in enumerate(pov.index): _lbl = 'pre-COVID (total = {} mil.)'.format(round( pov['init'].sum(), 1)) if _n == 0 else '' plt.plot([3 * _n, 3 * _n + 2], [pov.loc[_, 'init'], pov.loc[_, 'init']], lw=1, color=greys_pal[6], zorder=90, label=_lbl) plt.bar([3 * _ for _ in range(len(pov.index))], pov['covid'], facecolor=mc.sns_pal[2], lw=0, width=1, alpha=0.6, label='COVID shock ({} mil.)'.format(round(pov['covid'].sum(), 1)), zorder=80) plt.bar([3 * _ + 1 for _ in range(len(pov.index))], pov['ESP'], facecolor=mc.sns_pal[1], lw=0, width=1, alpha=0.6, label='with SAP benefits ({} mil.)'.format( round(pov['ESP'].sum(), 1)), zorder=80) plt.grid(True, axis='y', alpha=0.3) plt.legend(loc='upper left', labelspacing=0.75, ncol=1, fontsize=8, borderpad=0.75, fancybox=True, frameon=True, framealpha=0.9) plt.xticks([3 * _ + 1 for _ in range(len(pov.index))], pov.index, rotation=90) plt.ylabel('Poverty incidence [mil.]', labelpad=10) sns.despine(left=True) plt.savefig('figs/regional_poverty.pdf', format='pdf', bbox_inches='tight') plt.close('all')
def plot_income_profile(hh_df, affected_only=False): pal = monte_carlo().ichan_cols _ul = 500 nbins = int(40) # total income <-- use to structure plot tot_hgt, _bins = np.histogram(hh_df.eval('pcinc_initial').clip(upper=_ul), bins=nbins, weights=hh_df['popwgt']) wid = (_bins[1] - _bins[0]) frac_nonag_hgt = [] frac_ag_hgt = [] frac_totent_hgt = [] frac_public_hgt = [] frac_remit_hgt = [] frac_dom_remit_hgt = [] for n, b in enumerate(_bins): try: bin_slice = '(pcinc_initial>@b)&(pcinc_initial<=@_bins[@n+1]){}'.format( '&(income_loss>0)' if affected_only else '') frac_nonag_hgt.append( float(hh_df.loc[hh_df.eval(bin_slice)].eval( '1E2*popwgt*nonagri_sal').sum() / hh_df.loc[hh_df.eval( bin_slice)].eval('popwgt*hhinc').sum())) frac_ag_hgt.append( float(hh_df.loc[hh_df.eval(bin_slice)].eval( '1E2*popwgt*agri_sal').sum() / hh_df.loc[hh_df.eval( bin_slice)].eval('popwgt*hhinc').sum())) frac_public_hgt.append( float(hh_df.loc[hh_df.eval(bin_slice)].eval( '1E2*popwgt*total_public').sum() / hh_df.loc[hh_df.eval( bin_slice)].eval('popwgt*hhinc').sum())) frac_remit_hgt.append( float(hh_df.loc[hh_df.eval(bin_slice)].eval( '1E2*popwgt*cash_abroad').sum() / hh_df.loc[hh_df.eval( bin_slice)].eval('popwgt*hhinc').sum())) frac_dom_remit_hgt.append( float(hh_df.loc[hh_df.eval(bin_slice)].eval( '1E2*popwgt*cash_domestic').sum() / hh_df.loc[hh_df.eval( bin_slice)].eval('popwgt*hhinc').sum())) frac_totent_hgt.append( float(hh_df.loc[hh_df.eval(bin_slice)].eval( '1E2*popwgt*total_entrepreneurial').sum() / hh_df.loc[ hh_df.eval(bin_slice)].eval('popwgt*hhinc').sum())) except: pass _btm = [0 for _ in frac_remit_hgt] for istream in [[frac_totent_hgt, 'entrepreneurial', pal['entrep']], [frac_nonag_hgt, 'wages (non-ag)', pal['nonag_wage']], [frac_ag_hgt, 'agricultural wages', pal['ag_wage']], [frac_public_hgt, 'public transfers', pal['pub_trans']], [frac_remit_hgt, 'intl. remittances', pal['remits']], [ frac_dom_remit_hgt, 'domestic remittances', pal['dom_remits'] ]]: ax = plt.bar(_bins[:-1], istream[0], bottom=_btm, width=wid, align='edge', linewidth=0, alpha=0.6, facecolor=istream[2], label=istream[1]) _btm = [i + j for i, j in zip(_btm, istream[0])] plt.legend(loc='center right', labelspacing=0.75, ncol=1, fontsize=8, borderpad=0.75, fancybox=True, frameon=True, framealpha=0.9) plt.xlabel('pre-COVID income [PPP$/cap/month]', labelpad=8) plt.ylabel('fraction of total income [%]', labelpad=8) plt.xlim(0) plt.ylim(0, 100) plt.grid(True, axis='y', alpha=0.3) sns.despine(left=True) #plt.plot([0,_ul],[0,0],color=greys_pal[4],lw=1) plt.savefig('figs/income_composition{}.pdf'.format( '_affected_only' if affected_only else ''), format='pdf', bbox_inches='tight') plt.close('all')
def plot_sectoral_income(plot_losses=False): fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 7)) df = pd.read_csv('monte_carlo/sectoral_income_by_decile.csv', index_col=['decile', 'LFS_sector']).sort_index() df[['nonagri_sal', 'agri_sal', 'nonag_wage_loss', 'ag_wage_loss']] *= 1E-3 df_sum = df.sum(level='LFS_sector') df_sum.loc['total'] = df_sum.sum(axis=0) # split into 2 dfs: categories > (threshold)%, and all others threshold = 0.07 df_sum_other = df_sum.drop( 'ag', axis=0).loc[df_sum['nonagri_sal'] < threshold * float(df_sum.loc['total', 'nonagri_sal'])] # get categories > (threshold)% df_sum = df_sum.loc[df_sum['nonagri_sal'] >= threshold * float(df_sum.loc['total', 'nonagri_sal'])].drop( 'total', axis=0) df_sum.loc['remaining categories'] = df_sum_other.sum(axis=0) # put this info back into decile-level df df_other = df.reset_index().set_index('LFS_sector').loc[df_sum_other.index] df_other = df_other.reset_index().set_index(['decile', 'LFS_sector' ]).sum(level='decile') df_other['LFS_sector'] = 'remaining categories' # drop other sectors from df df = df.reset_index().set_index('LFS_sector').drop(df_sum_other.index, axis=0) # merge df = pd.concat([df.reset_index(), df_other.reset_index()], ignore_index=True).set_index(['decile', 'LFS_sector' ]).sort_index().reset_index() # merge ag & non-ag columns df['wage_loss'] = df['nonag_wage_loss'].copy() df.loc[df.LFS_sector == 'ag', 'wage_loss'] = df.loc[df.LFS_sector == 'ag', 'ag_wage_loss'] df['total_wages'] = df['nonagri_sal'].copy() df.loc[df.LFS_sector == 'ag', 'total_wages'] = df.loc[df.LFS_sector == 'ag', 'agri_sal'] df.drop(['nonag_wage_loss', 'ag_wage_loss', 'nonagri_sal', 'agri_sal'], axis=1, inplace=True) # calculate sectoral contribution to wage income, by decile df['sector_frac_total_wages'] = df['total_wages'] / df.groupby( 'decile')['total_wages'].transform('sum') df['sector_losses_frac_total_wages'] = df['wage_loss'] / df.groupby( 'decile')['total_wages'].transform('sum') # plotz # left subplot: total value of each sector plt.axes(ax[0]) output_col = 'wage_loss' if plot_losses else 'total_wages' bot = [0 for _ in range(1, 11)] sectors = df.LFS_sector.unique() for _n, _sec in enumerate( np.append(sectors[sectors != 'remaining categories'], 'remaining categories')): try: sec_lbl = monte_carlo().sector_labels[_sec] except: sec_lbl = _sec ddf = df.loc[df['LFS_sector'] == _sec] plt.bar(ddf['decile'], ddf[output_col], bottom=bot, label=sec_lbl, facecolor=sns_pal[_n], alpha=0.7, lw=0) bot += np.array(ddf[output_col].squeeze().T) plt.xlim(0.75, 11) plt.xticks([_ + 0.4 for _ in range(1, 11)], range(1, 11), linespacing=0.80, fontsize=9, ha='center') plt.xlabel('Income decile', fontsize=9, labelpad=10) plt.yticks([0.5 * _ for _ in range(1, 8)], linespacing=0.80, fontsize=9, ha='center') plt.ylabel('Wage income {}[billion PPP\$]'.format( 'losses ' if plot_losses else ''), fontsize=9, labelpad=10) plt.grid(True, axis='y', alpha=0.3) plt.legend(loc='upper left', labelspacing=0.75, ncol=1, fontsize=8, borderpad=0.75, fancybox=True, frameon=True, framealpha=0.9) sns.despine(left=True) # right subplot: relative contribution of each sector to total wage inome plt.axes(ax[1]) output_col = 'sector_losses_frac_total_wages' if plot_losses else 'sector_frac_total_wages' bot = [0 for _ in range(1, 11)] sectors = df.LFS_sector.unique() for _n, _sec in enumerate( np.append(sectors[sectors != 'remaining categories'], 'remaining categories')): try: sec_lbl = monte_carlo().sector_labels[_sec] except: sec_lbl = _sec ddf = df.loc[df['LFS_sector'] == _sec] plt.bar(ddf['decile'], ddf[output_col], bottom=bot, label=sec_lbl, facecolor=sns_pal[_n], alpha=0.7, lw=0) bot += np.array(ddf[output_col].squeeze().T) plt.xlim(0.75, 11) plt.xticks([_ + 0.4 for _ in range(1, 11)], range(1, 11), linespacing=0.80, fontsize=9, ha='center') plt.xlabel('Income decile', fontsize=9, labelpad=10) plt.ylim(0, 1) plt.yticks([0.2 * _ for _ in range(1, 6)], linespacing=0.80, fontsize=9, ha='center') plt.ylabel('Fraction of total wage income {}[%]'.format( 'lost ' if plot_losses else ''), fontsize=9, labelpad=10) plt.grid(True, axis='y', alpha=0.3) plt.savefig('figs/wage_income_sectoral_{}.pdf'.format( 'losses' if plot_losses else 'composition'), format='pdf', bbox_inches='tight') plt.close('all')
def plot_losses_total_value(scode): plt.gcf().set_size_inches(6, 8) barwid = 2 ########################################## # LOAD RESULTS # wage sector total value wage_val = pd.read_csv( 'monte_carlo/{}/total_value_wages.csv'.format(scode), index_col=0).multiply(1E-3) tot_wage_val = wage_val.sum(axis=1).mean() # wage sector losses wage_loss = pd.read_csv( 'monte_carlo/{}/total_loss_wages.csv'.format(scode), index_col=0).multiply(1E-3) tot_wage_loss = wage_loss.sum(axis=1).mean() ##### # entrepreneurial total value ent_val = pd.read_csv('monte_carlo/{}/total_value_ent.csv'.format(scode), index_col=0).multiply(1E-3) tot_ent_val = ent_val.sum(axis=1).mean() # entrepreneurial losses ent_loss = pd.read_csv('monte_carlo/{}/total_loss_ent.csv'.format(scode), index_col=0).multiply(1E-3) tot_ent_loss = ent_loss.sum(axis=1).mean() ##### # remittances total value remits_value = pd.read_csv( 'monte_carlo/{}/total_value_remits.csv'.format(scode), index_col=0).multiply(1E-3) intl_remits_val = remits_value['intl'].mean() # remittances losses remits_loss = pd.read_csv( 'monte_carlo/{}/total_loss_remits.csv'.format(scode), index_col=0).multiply(1E-3) tot_remits_loss = remits_loss.sum(axis=1).mean() ##### # total economic value economic_value = pd.read_csv( 'monte_carlo/{}/total_value_economy.csv'.format(scode), index_col=0).multiply(1E-3) total_economic_val = economic_value['income'].mean() total_economic_loss = economic_value['loss'].mean() # concat & transpose #value = pd.concat([wage_val,ent_val], axis=1) loss = pd.concat([wage_loss, ent_loss, remits_loss], axis=1).T loss['avg'] = loss.mean(axis=1) loss = loss.loc[loss.avg > 5E-2 * loss['avg'].max()] loss = loss.sort_values(by='avg', ascending=True).drop('avg', axis=1).T # coloring # pal = monte_carlo(0,'base').ichan_cols # colors = [pal['nonag_wage'] if _ in wage_loss.columns else (pal['entrep'] if _ in ent_loss.columns else pal['remits']) for _ in loss.columns] # joyplot min_loss = loss.min(axis=0) d_loss = loss.max(axis=0) - loss.min(axis=0) mean_loss = loss.mean(axis=0) joyplot_loss = loss.T.stack().reset_index() joyplot_loss.columns = ['wage_sector', 'nsim', 'result'] joyplot_grouped = joyplot_loss.groupby('wage_sector', sort=False) sector_labels = monte_carlo(0, 'base').sector_labels _ylabelsA = [ _ + ' (w)' if _ in wage_loss.columns else (_ + ' (e)' if _ in ent_loss.columns else _ + 'xxxx') for _ in loss.columns ] _ylabels = [(sector_labels[_[:-4]] + _[-4:]).lower().replace('xxxx', '') if _[:-4] in sector_labels else _.lower() for _ in _ylabelsA] fig, axes = joypy.joyplot(joyplot_grouped, column='result', by='wage_sector', overlap=3, x_range=[0, 1.20], grid='y', figsize=(10, 10), linewidth=0.02, alpha=0.8, ylabelsize=15, xlabelsize=15, labels=_ylabels, range_style='own', colormap=cm.RdYlGn_r) for n, y in enumerate(loss.columns): if mean_loss[y] != 0: axes[n].plot( [loss.quantile(.25, axis=0)[y], loss.quantile(.25, axis=0)[y]], [-2, 2], lw=1., color=greys_pal[7], zorder=99, clip_on=False) axes[n].plot( [loss.quantile(.75, axis=0)[y], loss.quantile(.75, axis=0)[y]], [-2, 2], lw=1.0, color=greys_pal[7], zorder=99, clip_on=False) axes[n].plot( [loss.quantile(.25, axis=0)[y], loss.quantile(.75, axis=0)[y]], [0, 0], lw=1.0, color=greys_pal[7], zorder=99, clip_on=False) axes[n].annotate( round(mean_loss[y], 2), xy=(mean_loss[y], 0.05 - (-1 if _ylabels[n] == 'wholesale (w)' else 1.5)), fontsize=9, ha='center', annotation_clip=False, zorder=100, va=('bottom' if _ylabels[n] == 'wholesale (w)' else 'top'), color=("white" if _ylabels[n] == 'wholesale (w)' else greys_pal[7])) else: plt.annotate('no impact', xy=(mean_loss[y] + 0.95, n + 0.9), fontsize=7, ha='left', va='center', weight='bold', zorder=92, style='italic') # loss = loss.T.stack().reset_index() # loss.columns = ['sector','sim','loss_value'] # Editing /Users/brian/Software/anaconda3/lib/python3.5/site-packages/seaborn/categorical.py (draw_box_lines) to customize # sns.violinplot(x='loss_value', y='sector', data=loss, scale='count', inner='box',cut=0,palette=colors,saturation=0.6,linewidth=0.05) # sectoral labels sector_labels = monte_carlo(0, 'base').sector_labels seclabels = [ sector_labels[_] if _ in sector_labels else _.lower() for _ in loss.columns ] plt.yticks([barwid / 2 + _ * 1.4 for _ in range(len(loss.columns))], seclabels, linespacing=0.80, fontsize=9) # totals plt.annotate('Monthly losses', xy=(0.655, 0.868), xycoords='axes fraction', ha='left', va='top', fontsize=14, weight='bold') anno1 = round(1E2 * economic_value['loss'].quantile(.25) / 699.258, 1) anno2 = round(1E2 * economic_value['loss'].quantile(.75) / 699.258, 1) annostr = (r'PPP\${} $\endash$ {} bil.'.format( round(economic_value['loss'].quantile(.25), 1), round(economic_value['loss'].quantile(.75), 1)) + '\n' + r'{}%$\endash${}% of total income'.format( round( 1E2 * (economic_value['loss'].quantile(.25)) / total_economic_val, 1), round( 1E2 * (economic_value['loss'].quantile(.75)) / total_economic_val, 1), round(total_economic_val, 1)) + '\n' + r'{}%$\endash${}% of GDP per month'.format(anno1, anno2)) plt.annotate(annostr, xy=(0.985, 0.838), xycoords='axes fraction', ha='right', va='top', fontsize=12, linespacing=1.25, zorder=100) # wages annostr = ('(w) wage sectors:\nPPP\${} $\endash$ {} bil.'.format( round(wage_loss.sum(axis=1).quantile(0.25), 1), round(wage_loss.sum(axis=1).quantile(0.75), 1) ) + r' ({}%$\endash${}%)'.format( int(round(1E2 * wage_loss.sum(axis=1).quantile(0.25) / tot_wage_val)), int(round(1E2 * wage_loss.sum(axis=1).quantile(0.75) / tot_wage_val)), round(tot_wage_val, 1))) plt.annotate(annostr, xy=(0.655, 0.758), xycoords='axes fraction', ha='left', va='top', fontsize=12, linespacing=1.25, zorder=100) # entrepreneurial annostr = ( '(e) entrepreneurial sectors:\nPPP\${} $\endash$ {} bil.'.format( round(ent_loss.sum(axis=1).quantile(0.25), 1), round(ent_loss.sum(axis=1).quantile(0.75), 1)) + r' ({}%$\endash${}%)'.format( int(round( 1E2 * ent_loss.sum(axis=1).quantile(0.25) / tot_ent_val)), int(round(1E2 * ent_loss.sum(axis=1).quantile(0.75) / tot_ent_val)), round(tot_ent_val, 1))) plt.annotate(annostr, xy=(0.655, 0.700), xycoords='axes fraction', ha='left', va='top', fontsize=12, linespacing=1.25, zorder=100) # remittances q25a = round(remits_loss['intl'].quantile(0.25), 1) q75a = round(remits_loss['intl'].quantile(0.75), 1) q25b = int( round(1E2 * remits_loss['intl'].quantile(0.25) / intl_remits_val)) q75b = int( round(1E2 * remits_loss['intl'].quantile(0.75) / intl_remits_val)) if q25a != q75a: annostr = ( 'international remittances:\nPPP\${} $\endash$ {} bil.'.format( q25a, q75a) + r' ({}%$\endash${}%)'.format(q25b, q75b)) else: annostr = ('international remittances:\nPPP\${} bil.'.format(q25a) + r' ({}%)'.format(q25b)) plt.annotate(annostr, xy=(0.655, 0.643), xycoords='axes fraction', ha='left', va='top', fontsize=12, linespacing=1.25, zorder=100) # need to add bbox behind annotations # x-ax label plt.xlabel('Aggregate loss [billion PPP$/month]', labelpad=10, fontsize=15) plt.grid(True, axis='y', alpha=0.5, zorder=80) sns.despine(left=True) plt.savefig('figs/sectoral_losses_total_value.pdf', format='pdf', bbox_inches='tight') plt.close('all')
def plot_sectoral_impacts(scode): pal = monte_carlo().ichan_cols ################################################### # wage sectors (LFS) mc_floss = pd.read_csv('monte_carlo/{}/frac_loss_wages.csv'.format(scode), index_col=0).T try: mc_floss = mc_floss.drop('unemployed', axis=0) except: pass try: mc_floss = mc_floss.drop('unclassified', axis=0) except: pass mc_floss['avg'] = mc_floss.mean(axis=1) mc_floss.sort_values(by='avg', ascending=True, inplace=True) mc_floss = mc_floss.drop(['avg'], axis=1).T #mc_loss = pd.read_csv('monte_carlo/{}/total_loss_wages.csv'.format(scode),index_col=0) #mc_value = pd.read_csv('monte_carlo/{}/total_value_wages.csv'.format(scode),index_col=0) min_floss = mc_floss.min(axis=0) d_floss = mc_floss.max(axis=0) - mc_floss.min(axis=0) mean_floss = mc_floss.mean(axis=0) joyplot_floss = mc_floss.T.stack().reset_index() joyplot_floss.columns = ['wage_sector', 'nsim', 'result'] joyplot_grouped = joyplot_floss.groupby('wage_sector', sort=False) sector_labels = monte_carlo(0, 'base').sector_labels _ylabels = [ sector_labels[_] if _ in sector_labels else _.lower() for _ in mc_floss.columns ] fig, axes = joypy.joyplot(joyplot_grouped, column='result', by='wage_sector', overlap=3, x_range=[0, 100], grid='y', figsize=(10, 10), colormap=cm.RdYlGn_r, linewidth=0.02, alpha=0.8, ylabelsize=15, xlabelsize=15, labels=_ylabels, range_style='own') up_cats = ['government', 'information', 'agriculture'] for n, y in enumerate(mc_floss.columns): if mean_floss[y] != 0: axes[n].plot([ mc_floss.quantile(.25, axis=0)[y], mc_floss.quantile(.25, axis=0)[y] ], [-0.01, 0.01], lw=1., color=greys_pal[7], zorder=99, clip_on=False) axes[n].plot([ mc_floss.quantile(.75, axis=0)[y], mc_floss.quantile(.75, axis=0)[y] ], [-0.01, 0.01], lw=1.0, color=greys_pal[7], zorder=99, clip_on=False) axes[n].plot([ mc_floss.quantile(.25, axis=0)[y], mc_floss.quantile(.75, axis=0)[y] ], [0, 0], lw=1.0, color=greys_pal[7], zorder=99, clip_on=False) axes[n].annotate( '{}'.format(int(round(mean_floss[y]))), xy=(mean_floss[y], 0.005 - (-0.00 if _ylabels[n] in up_cats else 0.01)), fontsize=9, ha='center', annotation_clip=False, zorder=100, va=('bottom' if _ylabels[n] in up_cats else 'top'), color=("white" if _ylabels[n] in up_cats else greys_pal[7])) # axes[n].plot([mean_floss[y],mean_floss[y]],[0,0.055],lw=2.0,color=greys_pal[7],zorder=100) # axes[n].annotate('{}%'.format(int(round(mean_floss[y]))),xy=(mean_floss[y]+1,0.025),fontsize=10,ha='left',va='top',weight='bold',zorder=92,color=greys_pal[8]) else: plt.annotate('no impact', xy=(mean_floss[y] + 0.95, n + 0.9), fontsize=7, ha='left', va='center', weight='bold', zorder=92, style='italic') # plt.yticks([0.9+_ for _ in range(0,len(mc_floss.columns))],_ylabels) plt.xticks([0, 20, 40, 60, 80, 100], ['0%', '20%', '40%', '60%', '80%', '100%']) plt.xlabel('Total income loss, by wage sector', labelpad=10, fontsize=15) plt.grid(False) #True,axis='x',alpha=1.0) sns.despine(left=True, bottom=True) plt.savefig('figs/sectoral_losses_wage.pdf', format='pdf', bbox_inches='tight') plt.close('all') ################################################### # entrepreneurial sectors (FIES-prescribed sectors) ################################################### # wage sectors (LFS) mc_floss = pd.read_csv('monte_carlo/{}/frac_loss_ent.csv'.format(scode), index_col=0).T mc_floss['avg'] = mc_floss.mean(axis=1) mc_floss.sort_values(by='avg', ascending=True, inplace=True) mc_floss = mc_floss.drop(['avg'], axis=1).T #mc_loss = pd.read_csv('monte_carlo/{}/total_loss_wages.csv'.format(scode),index_col=0) #mc_value = pd.read_csv('monte_carlo/{}/total_value_wages.csv'.format(scode),index_col=0) min_floss = mc_floss.min(axis=0) d_floss = mc_floss.max(axis=0) - mc_floss.min(axis=0) mean_floss = mc_floss.mean(axis=0) joyplot_floss = mc_floss.T.stack().reset_index() joyplot_floss.columns = ['wage_sector', 'nsim', 'result'] joyplot_grouped = joyplot_floss.groupby('wage_sector', sort=False) sector_labels = monte_carlo(0, 'base').sector_labels _ylabels = [ sector_labels[_] if _ in sector_labels else _.lower() for _ in mc_floss.columns ] fig, axes = joypy.joyplot(joyplot_grouped, column='result', by='wage_sector', overlap=3, x_range=[0, 100], grid='y', figsize=(10, 10), colormap=cm.RdYlGn_r, linewidth=0.02, alpha=0.8, ylabelsize=15, xlabelsize=15, labels=_ylabels, range_style='own') up_cats = ['fishing', 'livestock & poultry', 'crop farming & gardening'] for n, y in enumerate(mc_floss.columns): if mean_floss[y] != 0: axes[n].plot([ mc_floss.quantile(.25, axis=0)[y], mc_floss.quantile(.25, axis=0)[y] ], [-0.01, 0.01], lw=1., color=greys_pal[7], zorder=99, clip_on=False) axes[n].plot([ mc_floss.quantile(.75, axis=0)[y], mc_floss.quantile(.75, axis=0)[y] ], [-0.01, 0.01], lw=1.0, color=greys_pal[7], zorder=99, clip_on=False) axes[n].plot([ mc_floss.quantile(.25, axis=0)[y], mc_floss.quantile(.75, axis=0)[y] ], [0, 0], lw=1.0, color=greys_pal[7], zorder=99, clip_on=False) axes[n].annotate( '{}'.format(int(round(mean_floss[y]))), xy=(mean_floss[y], 0.005 - (-0.0 if _ylabels[n] in up_cats else 0.01)), fontsize=9, ha='center', annotation_clip=False, zorder=100, va=('bottom' if _ylabels[n] in up_cats else 'top'), color=("white" if _ylabels[n] in up_cats else greys_pal[7])) # axes[n].plot([mean_floss[y],mean_floss[y]],[0,0.055],lw=2.0,color=greys_pal[7],zorder=100) # axes[n].annotate('{}%'.format(int(round(mean_floss[y]))),xy=(mean_floss[y]+1,0.025),fontsize=10,ha='left',va='top',weight='bold',zorder=92,color=greys_pal[8]) else: plt.annotate('no impact', xy=(mean_floss[y] + 0.95, n + 0.9), fontsize=7, ha='left', va='center', weight='bold', zorder=92, style='italic') # plt.yticks([0.9+_ for _ in range(0,len(mc_floss.columns))],_ylabels) plt.xticks([0, 20, 40, 60, 80, 100], ['0%', '20%', '40%', '60%', '80%', '100%']) plt.xlabel('Total income loss, by entrepreneurial sector', labelpad=10, fontsize=15) plt.grid(False) #True,axis='x',alpha=1.0) sns.despine(left=True, bottom=True) plt.savefig('figs/sectoral_losses_entrepreneurial.pdf', format='pdf', bbox_inches='tight') plt.close('all')