Party Manifesto 'Redistributiveness' vs Electorate Income

In [140]:
# from IPython.display import display
# from IPython.display import HTML
# import IPython.core.display as di # Example: di.display_html('<h3>%s:</h3>' % str, raw=True)

# # This line will hide code by default when the notebook is exported as HTML
# di.display_html('<script>jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>', raw=True)

# # This line will add a button to toggle visibility of code blocks, for use with the HTML export version
# di.display_html('''<button onclick="jQuery('.input_area').toggle(); jQuery('.prompt').toggle();">Toggle code</button>''', raw=True)
In [141]:
%%time
%matplotlib inline
%run Prosser_header.py

dataset_folder = "C:\\Users\\Marios\\Documents\\GitHub\\Thomas Prosser project\\datasets\\"
output_folder  = "C:\\Users\\Marios\\Documents\\GitHub\\Thomas Prosser project\\output\\"
Wall time: 6 ms
In [142]:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import re, os
import pickle

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show,  output_notebook
from bokeh.layouts import column, row
from bokeh.embed import components
from bokeh.transform import factor_cmap
from bokeh.models import HoverTool
from bokeh.models import Span, Label
from bokeh.models import BoxAnnotation


output_notebook()
Loading BokehJS ...
In [143]:
def weighted_mean(x, **kws):
    val, weight = map(np.asarray, zip(*x))
    val, weight = val[~np.isnan(val)],weight[~np.isnan(val)]
    return (val * weight).sum() / weight.sum()

flatten = lambda l: [item for sublist in l for item in sublist]
In [144]:
dataset_folder = "C:\\Users\\Marios\\Documents\\GitHub\\Thomas Prosser project\\datasets\\"
output_folder = "C:\\Users\\Marios\\Documents\\GitHub\\Thomas Prosser project\\output\\"

Manifesto_Project_Dataset_version_2019b = "MPDataset_MPDS2019b_stata14.dta"

manifest_project = pd.read_pickle(dataset_folder+Manifesto_Project_Dataset_version_2019b.replace("dta","zip"),compression='zip')
with open(Manifesto_Project_Dataset_version_2019b.replace("dta","_labels.zip"), 'rb') as fname:
    ESS_labels = pickle.load(fname)
with open(Manifesto_Project_Dataset_version_2019b.replace("dta","_header.zip"), 'rb') as fname:
    ESS_header = pickle.load(fname)


EuropeanSocialSurvey9_2018_v2_integrated = "ESS9e02.dta"

ESS = pd.read_pickle(dataset_folder+EuropeanSocialSurvey9_2018_v2_integrated.replace("dta","zip"),compression='zip')
with open(EuropeanSocialSurvey9_2018_v2_integrated.replace("dta","_labels.zip"), 'rb') as fname:
    ESS_labels = pickle.load(fname)
with open(EuropeanSocialSurvey9_2018_v2_integrated.replace("dta","_header.zip"), 'rb') as fname:
    ESS_header = pickle.load(fname)

Early Version using Manifesto Project Redistribution Support data and ESS 9 party supporter income data (manually linked!)

Income data 2018-2019, Party support for Redistribution most recent in CMP dataset (for major parties, most recent GE - for minor parties could be decades old!)
Appropriate as v rough overview
Support For Redistribution = Sum of % of positive references to redistribution/welfare
Support Base Affluence = (weighted) mean of party supporter income quintile
In [145]:
## Manual linkage of ESS party vote to CMP ids

min_voter_sample_size = 100

## ess party vote variables
vote_vars = ['prtvtcat',
 'prtvtdbe',
 'prtvtdbg',
 'prtvtgch',
 'prtvtbcy',
 'prtvtecz',
#  'prtvede1',
 'prtvede2',
 'prtvtgee',
 'prtvtees',
 'prtvtdfi',
 'prtvtdfr',
 'prtvtcgb',
 'prtvtahr',
 'prtvtfhu',
 'prtvtcie',
 'prtvtcit',
 'prtvblt1',
#  'prtvblt2',
#  'prtvblt3',
 'prtvtalv',
 'prtvtme',
 'prtvtgnl',
 'prtvtbno',
 'prtvtdpl',
 'prtvtcpt',
 'prtvtrs',
 'prtvtcse',
 'prtvtfsi',
 'prtvtdsk']

# this was tedious - and will have to update if looking at different period/reduce sample size!
ESS_big_parties_to_CMP_parties = {\x96VP':42520, 'SPÃ\x96':42320, 'FPÃ\x96':42420, 'Grüne':42110,#Austria
 'N-VA':21916, 'PS':21322, 'CD&V':21521,  'MR':21426,#Belgium
 'Grazhdani za evropeiÌ\x86sko razvitie na Bulgariya (GERB)':80510,
       'Balgarska sotsialisticheska partiya (BSP)':80220,
       'Dvizhenie za prava i svobodi (DPS)':80951,#Bulgaria 
       'Social Democratic Party / Socialist Party':43320, 'FDP. The Liberals':43420,
           "Swiss People's Party":43810,#Swizterland
       'Democratic Rally (DISY)':55711,#Cyprus
       'ANO 2011':82430,'ODS':82413, \x8cSSD':82320,
         \x8ceská pirátská strana':82953, 'KSÄ\x8cM':82220,#Czechia
       'Christian Democratic Union/Christian Social Union (CDU/CSU)':41521,
           'Social Democratic Party (SPD)':41320,
           'Alliance 90/The Greens (Bündnis 90/Die Grünen)':41113,
           'Free Democratic Party (FDP)':41420, 'The Left (Die Linke)':41223,
           'Alternative for Germany (AFD)':41953,#Germany
       'Eesti Reformierakond':83430,
       'Eesti Keskerakond':83411, 'Sotsiaaldemokraatlik Erakond':83410,
       'Erakond Isamaa ja Res Publica Liit':83611,#Estonia
       'PSOE':33320, 'PP':33610,'Unidas Podemos':33210, 'VOX':np.nan,#Spain
       'The National Coalition Party':14620,
           'The Centre Party':14810, 'Social Democratic Party':14320, 'Green League':14110,
           'True Finns':14820,#Finland
     'LREM (LA RÃ\x89PUBLIQUE EN MARCHE)':31425,
       'LR (LES RÃ\x89PUBLICAINS)':31626, 'PS (Parti Socialiste)':31320,
       'FN (Front National)':31720,#France
         'Conservative':51620, 'Labour':51320, 'Liberal Democrat':51421,#United Kingdom
 'Narodna koalicija - SDP, HNS, HSU, HSS':81032,  'Hrvatska demokratska zajednica (HDZ)':81711,#Croatia
       'Fidesz (Fidesz Magyar Polgári Párt)':86421,
       'Jobbik (Jobbik Magyarországért Mozgalom)':86710,
       'MSZP (Magyar Szocialista Párt)':86320,#Hungary
 'Fine Gael':53520, 'Fianna Fáil':53620,
       'Independent':53981, 'Sinn Féin':53951,#Ireland
 'Movimento 5 Stelle':32956,
       'Partido Democratico (PD)':32440, 'Lega Nord':32720,#Italy
       'Lithuanian Peasant and Greens Union (LVZS)':88820,
       'Homeland Union - Lithuanian Christian Democrats (TS-LKD)':88621,
       'Lithuanian Social Democratic Party (LSDP)':88320,#Lithuania
 
       'DPS - Milo Ä\x90ukanoviÄ\x87':91220,#Montenegro
 
       "People's Party for Freedom and Democracy":22955, "Democrats '66":22330,
       'Green Left':22110, 'Christian Democratic Appeal':22521,#Netherlands
 'Høyre':12620,
       'Arbeiderpartiet':12320, 'Fremskrittspartiet':12951,#Norway
       'Prawo i SprawiedliwoÅ\x9bÄ\x87':92436, 'Platforma Obywatelska':92435,#Poland
       'PS - Partido Socialista':35311,
       'PPD-PSD/CDS-PP - Portugal Ã\xa0 Frente':35313,#Portugal
       'Aleksandar VuÄ\x8d\x87-Srbija pobeÄ\x91uje':95071,#Serbia
       'Socialdemokraterna':11320, 'Moderata samlingspartiet':11620, 'Centern':11810,
       'Sverigedemokraterna':11710, 'Vänsterpartiet':11220,#Sweden
       'SDS - Slovenska demokratska stranka':97330,
       'LMÅ\xa0 - Lista Marjana Å\xa0arca':np.nan,#Slovenia
 'Smer â\x80\x93 SD':96423#Slovakia]
}


votes_country_dict = {x:re.sub("Party voted for in last national election\s?\d?, ","",ESS_header[x])\
                      .replace('France (ballot 1)',"France")\
                      .replace('Ireland (derived from 1st preference','Ireland')\
                      .replace('Lithuania (first vote, party)','Lithuania')
                      for x in vote_vars}

big_parties_by_country_dict = {}
for vote_var in votes_country_dict.keys():
    big_parties_by_country_dict[ votes_country_dict[vote_var] ] = list(ESS[vote_var].value_counts()[ESS[vote_var].value_counts()>=min_voter_sample_size].index)
big_parties_by_country_dict


# ESS[list(votes_country_dict.keys())].notnull().sum(axis=1).sort_values()
# note - checked, there's no overlap between different elections!

# get the overlap set for parties in both datasets who were in the most recent election
ESS_big_party_list_overlap = [x for x in ESS_big_parties_to_CMP_parties.keys() if pd.notnull(ESS_big_parties_to_CMP_parties[x])]
party_voted_in_last_nat_election = ESS[list(votes_country_dict.keys())].fillna(axis=1,method ='ffill')[list(votes_country_dict.keys())[-1]]
party_voted_in_last_nat_election.loc[party_voted_in_last_nat_election.apply(lambda x: x not in ESS_big_party_list_overlap)] = np.nan

# this is ... a bit much for one line!
voting_country = ESS[list(votes_country_dict.keys())].notnull().idxmax(axis=1).map(votes_country_dict)
voting_country.loc[party_voted_in_last_nat_election.apply(lambda x: x not in ESS_big_party_list_overlap)] = np.nan
In [146]:
## ESS income decile data

deciles = ESS['hinctnta'].cat.codes.replace(-1,np.nan)
ESS["income_deciles_wts"] = list(zip(deciles,ESS["pspwght"]))
weighted_income_deciles_by_party = ESS["income_deciles_wts"].groupby(party_voted_in_last_nat_election).agg(weighted_mean).sort_values().reset_index()
weighted_income_deciles_by_party.columns = ["party","mean_inc_decile"]
# weighted_income_deciles_by_party
In [147]:
#### FILTER BY PROGRAMME TYPE! (good to remember, but prob obsolete since we won't be relying on upon just the CMP measure long-term)
In [148]:
# another shocking single line function
cmp_overlap_df = manifest_project[manifest_project["party"].apply(lambda x: x in ESS_big_parties_to_CMP_parties.values())].sort_values(by="edate").groupby("party").last()
cmp_overlap_df = cmp_overlap_df.sort_index()
In [149]:
# "redistributiveness" measure
manifesto_redist = cmp_overlap_df[["per"+x for x in ["404","405","409","413","504","701"]]].sum(axis=1)
In [150]:
weighted_income_deciles_by_party["party"] = weighted_income_deciles_by_party["party"].map(ESS_big_parties_to_CMP_parties)
weighted_income_deciles_by_party = weighted_income_deciles_by_party.set_index("party")
weighted_income_deciles_by_party = weighted_income_deciles_by_party["mean_inc_decile"].sort_index()
In [151]:
cmp_overlap_df["weighted_income_deciles"] = weighted_income_deciles_by_party
cmp_overlap_df["manifesto_redist"] = manifesto_redist

cmp_overlap_df["partyabbrev_filled"] = cmp_overlap_df["partyabbrev"].astype('object')
cmp_overlap_df.loc[cmp_overlap_df["partyabbrev"]=="","partyabbrev_filled"] = cmp_overlap_df[cmp_overlap_df["partyabbrev"]==""]["partyname"].astype('object')
In [ ]:
 
In [152]:
party_colour_dict = {'eco ecologist':'green', 'lef socialist or other left':'pink', 'soc social democratic':'red',
       'lib liberal':'orange', 'chr christian democrat':'darkblue', 'con conservative':'lightblue',
       'nat nationalist':'purple', 'agr agrarian':'brown', 'eth ethnic-regional':'yellow',
       'sip special issue':'olive','dummy divers alliance':'black','dummy missing information':'grey'}

# {'divers alliance', 'missing information'}
In [153]:
cmp_overlap_df["Party Family"] = cmp_overlap_df["parfam"].apply(lambda x: (" ").join(x.split(" ")[1:]))
party_colour_dict = {(" ").join(k.split(" ")[1:]):v for k,v in party_colour_dict.items()}
In [154]:
## give the axes slightly more human legible names

x_axis = "Support Base Affluence"
y_axis = "Support For Redistribution"
cmp_overlap_df = cmp_overlap_df.rename(columns={"weighted_income_deciles":x_axis,"manifesto_redist":y_axis})
In [155]:
plt.figure(figsize=(12,8))
sns.scatterplot(data = cmp_overlap_df,x=x_axis,y=y_axis,
                hue="Party Family",palette=party_colour_dict);

# make size = percentage of the vote? "pervote"

def label_point(x, y, val, ax):
    a = pd.concat({'x': x, 'y': y, 'val': val}, axis=1)
    for i, point in a.iterrows():
        ax.text(point['x']+.02, point['y'], str(point['val']), fontsize=8)

label_point(cmp_overlap_df[x_axis],
            cmp_overlap_df[y_axis],
            cmp_overlap_df["partyabbrev_filled"], plt.gca())

plt.xlabel(x_axis);
plt.ylabel(y_axis);
# plt.gca().legend(title='Party Family');
In [ ]:
 
In [156]:
cmp_overlap_df["parfam"] = cmp_overlap_df["parfam"].cat.remove_unused_categories()
# cmp_overlap_df["parfam"].value_counts()
cmp_overlap_df["pervote_smaller"] = cmp_overlap_df["pervote"]/2
In [157]:
# colours = mps["party"].replace(party_colour_dict).values
colors = factor_cmap('Party Family', palette=list(party_colour_dict.values()), factors=list(party_colour_dict.keys()))

hover = HoverTool(tooltips = [('name','@partyname'),
                              ('party family','@{Party Family}'),
                              ('country','@countryname'),
                              ('date','@date'),
                              ('right-left','@rile'),
                              ('planned economy','@planeco'),
                              ('market economy','@markeco'),
                              ('welfare','@welfare'),
                              ('intpeace','@intpeace')])

p1 = figure(plot_width=950, plot_height=400, title="Party Manifesto 'Redistributiveness' by Mean Electorate Income Decile",
            tools='box_select,pan,wheel_zoom,box_zoom,reset', active_drag="box_select",
            x_axis_label = x_axis,y_axis_label=y_axis,)
for family in cmp_overlap_df["Party Family"].cat.categories:
    mask = cmp_overlap_df["Party Family"]==family
    source = ColumnDataSource(cmp_overlap_df[mask])
    p1.scatter(x_axis, y_axis, source=source,
               fill_color=party_colour_dict[family], line_color = party_colour_dict[family], alpha=0.7,
               legend_label=family,size='pervote_smaller')
    
#     p1.scatter('weighted_income_deciles', 'manifesto_redist', source=source, fill_color=colors, line_color = colors, alpha=0.7,
#               legend_group='parfam',size='pervote_smaller',)
p1.add_tools(hover)
p1.legend.location = "top_left"
p1.legend.click_policy="hide"
show(p1)
In [158]:
# cmp_overlap_df["edate"].min(),cmp_overlap_df["edate"].max(),

# 80 between 1994 and 2018

More advanced version using Partyfacts.org ids to link CSES and Manifesto project datasets

Income data from whole CSES period (1996-2016, some entries up to 2018 using latest released of Mod 5), Party support for Redistribution most recent in CMP dataset (for major parties, most recent GE - for minor parties could be decades old!)
Slightly less rough overview
Support For Redistribution = Sum of % of positive references to redistribution/welfare
Support Base Affluence = (weighted) mean of party supporter income quintile
Restricted to (EEA states + UK) only
In [215]:
## filter to only EEA countries and UK 

# Austria, Belgium, Bulgaria, Croatia, Republic of Cyprus, Czech Republic, Denmark, Estonia, Finland,
# France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands,
# Poland, Portugal, Romania, Slovakia, Slovenia, Spain, and Sweden.

EEA_and_UK_countries = ["AUT","BEL","BGR","HRV","CYP","CZE","DNK","EST","FIN","FRA","DEU","GRC","HUN","IRL","ITA","LVA","LTU","LUX",
 "MLT","NLD","POL","PRT","ROU","SVK","SVN","ESP","SWE","GBR"]
EEA_and_UK_parties = list(partyfacts_core_parties_newest.set_index("partyfacts_id")["country"].apply(lambda x: x if x in EEA_and_UK_countries else np.nan).dropna().index)
In [216]:
partyfacts_core_parties_newest = pd.read_csv(dataset_folder+"PartyFacts"+os.sep+"Newest version"+os.sep+"partyfacts-core-parties.csv")
partyfacts_external_parties_newest = pd.read_csv(dataset_folder+"PartyFacts"+os.sep+"Newest version"+os.sep+ "partyfacts-external-parties.csv")
partyfacts_countries = pd.read_csv(dataset_folder+"PartyFacts"+os.sep+ "partyfacts-countries.csv")
partyfacts_datasets = pd.read_csv(dataset_folder+"PartyFacts"+os.sep+ "partyfacts-datasets.csv")

# partyfacts_core_parties_newest[partyfacts_core_parties_newest["name_short"].isnull()]
## 

# 5307: Kokumin Kyōkai: no abbreviation - but "KK" seems to be free!
# 7619: National Alliance : "NA"
# 8081: National Union: "NU"??? (could be NA, but more distinct from National Alliance)
# 8454: Nauru First: No abbreviation ... because only party in Nauru I guess should be "NA" because name in Nauru?

partyfacts_core_parties_newest.loc[partyfacts_core_parties_newest["partyfacts_id"]==5307,"name_short"] = "KK"
partyfacts_core_parties_newest.loc[partyfacts_core_parties_newest["partyfacts_id"]==7619,"name_short"] = "NA"
partyfacts_core_parties_newest.loc[partyfacts_core_parties_newest["partyfacts_id"]==8081,"name_short"] = "NU"
partyfacts_core_parties_newest.loc[partyfacts_core_parties_newest["partyfacts_id"]==8454,"name_short"] = "NA"
In [217]:
output_df_mean = pd.read_pickle(dataset_folder + "CSES"+os.sep+"Integration"+os.sep+"respond_sample_broad_mean.pkl").set_index("partyfacts_id")
output_df_count = pd.read_pickle(dataset_folder + "CSES"+os.sep+"Integration"+os.sep+"respond_sample_broad_count.pkl").set_index("partyfacts_id")
output_df_std = pd.read_pickle(dataset_folder + "CSES"+os.sep+"Integration"+os.sep+"respond_sample_broad_std.pkl").set_index("partyfacts_id")

# output_df_mean.set_index("partyfacts_id")
In [218]:
df_merged = pd.read_pickle(dataset_folder+"Party Level"+os.sep+ "df_merged.zip",compression='zip')
df_merged = df_merged.reset_index().groupby("partyfacts_id").first()
manifesto_redist = df_merged[["(manifesto)per"+x for x in ["404","405","409","413","504","701"]]].sum(axis=1)

## some duplicates partyfacts_id here, but the manifesto data is identical in each case, so just just drop duplicates
manifesto_redist = manifesto_redist.reset_index().drop_duplicates().set_index("partyfacts_id")[0]
party_family = df_merged[search(df_merged,"\(manifesto\)family").index].idxmax(axis=1).apply(lambda x: x.replace("(manifesto)family__","") if pd.notnull(x) else np.nan)
party_family = party_family.reset_index().drop_duplicates().set_index("partyfacts_id")[0]
In [219]:
mean_inc_decile = output_df_mean["IMD2006_ORD"]
abbreviation = partyfacts_core_parties_newest.set_index("partyfacts_id")["name_short"]
ss_inc_decile = output_df_count["IMD2006_ORD"]
# ss_inc_decile.dropna()[ss_inc_decile.dropna()>100]

mean_inc_decile.loc[ss_inc_decile<100] = np.nan
# mean_inc_decile.dropna().shape

party_overlap = set(manifesto_redist.dropna().index).intersection(mean_inc_decile.dropna().index)

# 562 by income -> 405 by income + redist
# with ss >=100, 243 -> 208


## restrict to EEA and UK
party_overlap = [x for x in party_overlap if x in EEA_and_UK_parties]
In [ ]:
 
In [234]:
df =pd.DataFrame()
df[x_axis] = mean_inc_decile.loc[party_overlap]
df[y_axis] = manifesto_redist.loc[party_overlap]
df["Abbreviation"] = abbreviation.loc[party_overlap]
df["Party Family"] = party_family.loc[party_overlap]
# 29 missing party family values
df["Party Family"] = df["Party Family"].fillna("unknown").astype('category')

party_family_vc = df["Party Family"].value_counts()
df["Party Family"] = df["Party Family"].cat.rename_categories({k:k+" (N="+str(party_family_vc.loc[k])+")" for k in df["Party Family"].cat.categories})
In [235]:
df["pervote_smaller"] = df_merged[search(df_merged,"\(manifesto\)pervote").index].loc[party_overlap]/2
df["rile"] = df_merged[search(df_merged,"\(manifesto\)rile").index].loc[party_overlap]
df["planeco"] = df_merged[search(df_merged,"\(manifesto\)planeco").index].loc[party_overlap]
df["markeco"] = df_merged[search(df_merged,"\(manifesto\)markeco").index].loc[party_overlap]
df["welfare"] = df_merged[search(df_merged,"\(manifesto\)welfare").index].loc[party_overlap]
df["intpeace"] = df_merged[search(df_merged,"\(manifesto\)intpeace").index].loc[party_overlap]
In [236]:
df["partyname"] = partyfacts_core_parties_newest.set_index("partyfacts_id")["name_english"].loc[party_overlap]
df["abbrev"] = partyfacts_core_parties_newest.set_index("partyfacts_id")["name_short"].loc[party_overlap]
df["country"] = partyfacts_core_parties_newest.set_index("partyfacts_id")["country"].loc[party_overlap]
In [242]:
party_colour_dict = {'green':'green', 'rad left':'pink', 'socialist':'red',
       'liberal':'orange', 'christdem':'darkblue', 'cons':'lightblue',
       'rad right':'purple', 'agrarian':'brown', 'regional':'yellow',
       'special issue':'olive','coalition':'black','unknown':'grey'}
party_colour_dict = {k+" (N="+str(party_family_vc.loc[k])+")":v for k,v in party_colour_dict.items()}
In [ ]:
 
In [243]:
plt.figure(figsize=(12,8))
sns.scatterplot(data = df,x=x_axis,y=y_axis,
                hue="Party Family",palette=party_colour_dict);
# ,palette=party_colour_dict
# make size = percentage of the vote? "pervote"

def label_point(x, y, val, ax):
    a = pd.concat({'x': x, 'y': y, 'val': val}, axis=1)
    for i, point in a.iterrows():
        ax.text(point['x']+.02, point['y'], str(point['val']), fontsize=8)

label_point(df[x_axis],
            df[y_axis],
            df["Abbreviation"], plt.gca())

# plt.xlabel("Support Base Affluence");
# plt.ylabel("Support For Redistribution");
# plt.gca().legend(title='Party Family');
In [244]:
# colours = mps["party"].replace(party_colour_dict).values
colors = factor_cmap('Party Family', palette=list(party_colour_dict.values()), factors=list(party_colour_dict.keys()))

hover = HoverTool(tooltips = [('name','@partyname'),
                              ('abbrev','@abbrev'),
                              ('party family','@{Party Family}'),
                              ('country','@country'),
#                               ('date','@date'),
                              ('right-left','@rile'),
                              ('planned economy','@planeco'),
                              ('market economy','@markeco'),
                              ('welfare','@welfare'),
                              ('intpeace','@intpeace')])

p1 = figure(plot_width=950, plot_height=400, title="Party Manifesto 'Redistributiveness' by Mean Electorate Income Decile",
            tools='box_select,pan,wheel_zoom,box_zoom,reset', active_drag="box_select",
            x_axis_label = "Support Base Affluence",y_axis_label="Support For Redistribution",)
for family in df["Party Family"].cat.categories:
    mask = df["Party Family"]==family
    source = ColumnDataSource(df[mask])
    p1.scatter('Support Base Affluence', 'Support For Redistribution',source=source,
               fill_color=party_colour_dict[family], line_color = party_colour_dict[family], alpha=0.7,
               legend_label=family,size='pervote_smaller')
    
#     p1.scatter('weighted_income_deciles', 'manifesto_redist', source=source, fill_color=colors, line_color = colors, alpha=0.7,
#               legend_group='parfam',size='pervote_smaller',)
p1.add_tools(hover)
p1.legend.location = "top_left"
p1.legend.click_policy="hide"
show(p1)
In [247]:
left_wing_parties = ['green', 'liberal', 'rad left', 'socialist']
left_wing_parties = [k+" (N="+str(party_family_vc.loc[k])+")" for k in left_wing_parties]
title = "Party Manifesto 'Redistributiveness' by Mean Electorate Income Decile (Left-wing party families only)"

# colours = mps["party"].replace(party_colour_dict).values
colors = factor_cmap('Party Family', palette=list(party_colour_dict.values()), factors=list(party_colour_dict.keys()))

hover = HoverTool(tooltips = [('name','@partyname'),
                              ('abbrev','@abbrev'),
                              ('party family','@{Party Family}'),
                              ('country','@country'),
#                               ('date','@date'),
                              ('right-left','@rile'),
                              ('planned economy','@planeco'),
                              ('market economy','@markeco'),
                              ('welfare','@welfare'),
                              ('intpeace','@intpeace')])

p1 = figure(plot_width=950, plot_height=400, title=title,
            tools='box_select,pan,wheel_zoom,box_zoom,reset', active_drag="box_select",
            x_axis_label = "Support Base Affluence",y_axis_label="Support For Redistribution",)
for family in left_wing_parties:
    mask = df["Party Family"]==family
    source = ColumnDataSource(df[mask])
    p1.scatter('Support Base Affluence', 'Support For Redistribution',source=source,
               fill_color=party_colour_dict[family], line_color = party_colour_dict[family], alpha=0.7,
               legend_label=family,size='pervote_smaller')
    
#     p1.scatter('weighted_income_deciles', 'manifesto_redist', source=source, fill_color=colors, line_color = colors, alpha=0.7,
#               legend_group='parfam',size='pervote_smaller',)
p1.add_tools(hover)
p1.legend.location = "top_left"
p1.legend.click_policy="hide"
show(p1)
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [248]:
plt.figure(figsize=(12,8))
# df_merged["Party Family"] = party_family.fillna("unknown").astype('category')
sns.kdeplot( data = df,
             x = "Support Base Affluence",
             hue="Party Family",
             palette = party_colour_dict,
             cut=0);
In [249]:
plt.figure(figsize=(12,8))
# df_merged["Party Family"] = party_family.fillna("unknown").astype('category')
sns.kdeplot( data = df,
             x = "Support Base Affluence",
             hue="Party Family",
             palette = party_colour_dict,
             cut=0,multiple='stack');
In [250]:
plt.figure(figsize=(12,8))
# df_merged["Party Family"] = party_family.fillna("unknown").astype('category')
sns.kdeplot( data = df,
             x = "Support Base Affluence",
             hue="Party Family",
             palette = party_colour_dict,
             cut=0,multiple='fill');
In [ ]:
 
In [ ]:
 
In [202]:
 
In [ ]:
 
In [212]:
 
In [ ]:
 
In [ ]:
 

Comments

comments powered by Disqus