chorogrid tutorial, part 2A:

Chorogrid class

This is a continuation of part 2, focusing only on the Canadian federal ridings


In [1]:
# import the classes
from chorogrid import Colorbin, Chorogrid

In [2]:
mycolors = ['#b35806', '#f1a340', '#fee0b6', '#d8daeb', '#998ec3', '#542788']

Now to Canada. Here is a hex grid (made by me, using gephi) of the 338 federal electoral ridings defined in 2013; since each riding has approximately the same population, it is almost a cartogram. Ridings are colored according to province.


In [3]:
with open('chorogrid/databases/canada_federal_ridings_column_descriptions.txt', 'r', encoding='utf-8') as f:
    print(f.read())


district_code               Federal electoral district code
province                    Two-letter province postal abbreviation
federal_electoral_district  Name of federal riding
population                  Population in riding
electors                    Number of eligible voters in riding
area_km2                    Area of riding in square kilometers
square_x                    Horizontal position of square
square_y                    Vertical position of square
truecolhex_x                Horizontal position of hex with true columns
truecolhex_y                Vertical position of hex with true columns

In [4]:
# assign a different color to each district_code according to province

import pandas as pd
df = pd.read_csv('chorogrid/databases/canada_federal_ridings.csv')
provinces = df.province.unique()
province2color = {}
for i, province in enumerate(provinces):
    province2color[province] = mycolors[i % len(mycolors)]
canada_riding_colors = [province2color[province] for province in list(df.province)]

In [5]:
cg_ridings = Chorogrid('chorogrid/databases/canada_federal_ridings.csv', list(df.district_code), 
                       canada_riding_colors, 'district_code')
cg_ridings.set_title('Canadian federal ridings (hex grid)', font_dict={'font-size': 19})
cg_ridings.draw_hex('truecolhex_x', 'truecolhex_y', true_rows=False,
                    spacing_dict={'cell_width': 15, 'roundedness': 2},
                        font_dict={'fill-opacity': 0})
cg_ridings.done(show=True)


48001 48007 48012 48022 48034 48004 48008 48010 48020 48021 48005 48011 48018 48024 48026 48029 48031 48033 48003 48006 48009 48014 48015 48023 48028 48030 48002 48013 48016 48017 48019 48025 48027 48032 59009 59010 59018 59026 59027 59041 59025 59031 59037 59039 59011 59028 59034 59036 59040 59019 59030 59033 59038 59042 59003 59007 59035 59002 59008 59012 59016 59001 59021 59022 59023 59032 59004 59005 59006 59014 59017 59013 59015 59020 59024 59029 46001 46002 46007 46004 46011 46013 46014 46003 46005 46009 46012 46006 46008 46010 13003 13005 13010 13001 13006 13007 13008 13002 13004 13009 10004 10005 10003 10002 10001 10006 10007 12011 12006 12009 12003 12005 12007 12002 12004 12008 12001 12010 61001 62001 35042 35046 35091 35105 35117 35052 35083 35092 35106 35107 35112 35113 35116 35002 35008 35014 35026 35032 35040 35045 35048 35053 35103 35010 35011 35012 35017 35022 35051 35057 35080 35099 35100 35005 35009 35016 35025 35043 35047 35058 35062 35069 35111 35004 35013 35015 35029 35063 35065 35073 35082 35104 35121 35003 35030 35035 35054 35060 35072 35087 35118 35119 35120 35020 35027 35033 35034 35056 35059 35061 35070 35084 35115 35018 35023 35028 35037 35038 35049 35055 35086 35090 35021 35024 35036 35039 35041 35078 35081 35085 35093 35001 35031 35064 35068 35071 35079 35096 35101 35110 35114 35019 35044 35067 35075 35076 35077 35094 35097 35108 35109 35006 35007 35066 35074 35089 35095 35102 35050 35088 35098 11003 11004 11002 11001 24002 24027 24030 24057 24005 24013 24031 24035 24038 24029 24048 24050 24063 24033 24040 24056 24062 24065 24075 24003 24004 24012 24055 24068 24076 24078 24009 24015 24036 24052 24064 24069 24070 24074 24001 24021 24028 24032 24037 24053 24054 24058 24060 24071 24014 24019 24022 24025 24034 24039 24042 24045 24046 24049 24067 24077 24008 24011 24017 24020 24024 24043 24044 24059 24066 24010 24016 24018 24041 24051 24061 24072 24073 24006 24007 24023 24047 24026 47001 47002 47004 47010 47007 47011 47012 47003 47005 47006 47009 47008 47013 47014 60001 Canadian federal ridings (hex grid)

Now let's show what the results of the 2011 federal election (which had 308 ridings) would have looked like in the new 338-riding schema. Elections Canada has done the math, splitting up polling stations results into their new ridings at http://www.elections.ca/res/cir/trans2013/default.asp?lang=e. Under "Download file for all of Canada (CSV format – 1 file)", download "Download Grouped Polling Divisions". The resulting file, TRANSPOSITION_338FED.csv, has been included in Chorogrid's sample_data folder.


In [24]:
df_elxn = pd.read_csv('chorogrid/sample_data/TRANSPOSITION_338FED.csv', skiprows=4, encoding='latin-1', index_col=False)
df_elxn = df_elxn[['2013 FED Number', 'Conservative votes', 'NDP-New Democratic Party votes', 'Liberal votes', 'Bloc Québécois votes', 'Green Party votes']]
df_elxn.columns = ['FED', 'Con', 'NDP', 'Lib', 'BQ', 'Green']
df_elxn = pd.DataFrame(df_elxn.groupby('FED').sum())
df_elxn['winner'] = ''
for idx, row in df_elxn.iterrows():
    rowlist = list(row)[:5]
    winner = ['Conservative',
              'NDP',
              'Liberal',
              'Bloc Québécois',
              'Green'][rowlist.index(max(rowlist))]
    df_elxn.loc[idx, 'winner'] = winner
    
winner2colors = {'Conservative': '#3333aa',
                 'NDP': '#bb8811',
                 'Liberal': '#aa3333',
                 'Bloc Québécois': '#11bbbb',
                 'Green': '#33aa33'}

df = pd.read_csv('chorogrid/databases/canada_federal_ridings.csv')
canada_riding_colors = []
for idx, row in df.iterrows():
    fed = row.district_code
    winner = df_elxn.winner.ix[fed]
    canada_riding_colors.append(winner2colors[winner])
    
parties = list(winner2colors.keys())
parties.sort()
parties.reverse()
partycolors = [winner2colors[k] for k in parties]

In [29]:
cg_ridings = Chorogrid('chorogrid/databases/canada_federal_ridings.csv', list(df.district_code), 
                       canada_riding_colors, 'district_code')
cg_ridings.set_title('Canadian federal ridings (hex grid)', font_dict={'font-size': 19})
cg_ridings.set_legend(partycolors, parties)
cg_ridings.draw_hex('truecolhex_x', 'truecolhex_y', true_rows=False,
                    spacing_dict={'cell_width': 18, 'roundedness': 2, 'legend_offset': (-100,-50)},
                        font_dict={'fill-opacity': 0})
cg_ridings.done(show=True)


48001 48007 48012 48022 48034 48004 48008 48010 48020 48021 48005 48011 48018 48024 48026 48029 48031 48033 48003 48006 48009 48014 48015 48023 48028 48030 48002 48013 48016 48017 48019 48025 48027 48032 59009 59010 59018 59026 59027 59041 59025 59031 59037 59039 59011 59028 59034 59036 59040 59019 59030 59033 59038 59042 59003 59007 59035 59002 59008 59012 59016 59001 59021 59022 59023 59032 59004 59005 59006 59014 59017 59013 59015 59020 59024 59029 46001 46002 46007 46004 46011 46013 46014 46003 46005 46009 46012 46006 46008 46010 13003 13005 13010 13001 13006 13007 13008 13002 13004 13009 10004 10005 10003 10002 10001 10006 10007 12011 12006 12009 12003 12005 12007 12002 12004 12008 12001 12010 61001 62001 35042 35046 35091 35105 35117 35052 35083 35092 35106 35107 35112 35113 35116 35002 35008 35014 35026 35032 35040 35045 35048 35053 35103 35010 35011 35012 35017 35022 35051 35057 35080 35099 35100 35005 35009 35016 35025 35043 35047 35058 35062 35069 35111 35004 35013 35015 35029 35063 35065 35073 35082 35104 35121 35003 35030 35035 35054 35060 35072 35087 35118 35119 35120 35020 35027 35033 35034 35056 35059 35061 35070 35084 35115 35018 35023 35028 35037 35038 35049 35055 35086 35090 35021 35024 35036 35039 35041 35078 35081 35085 35093 35001 35031 35064 35068 35071 35079 35096 35101 35110 35114 35019 35044 35067 35075 35076 35077 35094 35097 35108 35109 35006 35007 35066 35074 35089 35095 35102 35050 35088 35098 11003 11004 11002 11001 24002 24027 24030 24057 24005 24013 24031 24035 24038 24029 24048 24050 24063 24033 24040 24056 24062 24065 24075 24003 24004 24012 24055 24068 24076 24078 24009 24015 24036 24052 24064 24069 24070 24074 24001 24021 24028 24032 24037 24053 24054 24058 24060 24071 24014 24019 24022 24025 24034 24039 24042 24045 24046 24049 24067 24077 24008 24011 24017 24020 24024 24043 24044 24059 24066 24010 24016 24018 24041 24051 24061 24072 24073 24006 24007 24023 24047 24026 47001 47002 47004 47010 47007 47011 47012 47003 47005 47006 47009 47008 47013 47014 60001 Bloc Québécois Conservative Green Liberal NDP Canadian federal ridings (hex grid)

Note that bolded provincial boundaries for the hex grid have not yet been implemented; it's on the to-do list.


In [7]:
cg_ridings = Chorogrid('chorogrid/databases/canada_federal_ridings.csv', list(df.district_code), 
                       canada_riding_colors, 'district_code')
cg_ridings.set_title('Canadian federal ridings (square grid)', font_dict={'font-size': 19})
cg_ridings.draw_squares(spacing_dict={'cell_width': 15, 'roundedness': 2},
                        font_dict={'fill-opacity': 0})
cg_ridings.done(show=True)

# Note that we passed list(df.district_code) as ids because our colors happened to be ordered the same as the
# ids in the database file. This is normally not the case, so we have to explicitly pass ids every time
# Chorogrid is instantiated.


10001 10002 10003 10004 10005 10006 10007 11001 11002 11003 11004 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 24001 24002 24003 24004 24005 24006 24007 24020 24008 24009 24010 24011 24012 24015 24016 24017 24019 24021 24022 24023 24024 24025 24026 24027 24028 24029 24030 24031 24032 24033 24034 24035 24036 24037 24038 24039 24040 24042 24041 24043 24044 24045 24046 24065 24047 24048 24049 24050 24051 24052 24053 24054 24055 24014 24056 24057 24058 24059 24060 24061 24018 24062 24063 24064 24066 24067 24068 24069 24070 24071 24072 24073 24075 24013 24076 24074 24077 24078 35001 35002 35003 35004 35005 35006 35007 35008 35009 35010 35011 35012 35013 35014 35015 35016 35088 35017 35018 35019 35020 35021 35022 35023 35024 35025 35026 35027 35028 35029 35030 35031 35032 35033 35034 35035 35036 35037 35038 35039 35121 35040 35041 35042 35043 35044 35045 35046 35047 35048 35049 35050 35051 35052 35053 35054 35055 35056 35057 35058 35059 35060 35061 35062 35063 35064 35065 35066 35067 35068 35069 35070 35071 35072 35073 35076 35074 35075 35077 35078 35079 35080 35081 35082 35083 35084 35085 35086 35087 35089 35091 35092 35093 35094 35095 35096 35097 35098 35099 35100 35101 35102 35103 35104 35105 35106 35107 35108 35109 35090 35110 35111 35112 35113 35114 35115 35116 35117 35118 35119 35120 46001 46002 46003 46004 46005 46006 46007 46008 46009 46010 46011 46012 46013 46014 47001 47004 47002 47003 47005 47006 47007 47008 47009 47010 47011 47012 47013 47014 48001 48002 48003 48004 48005 48006 48007 48008 48009 48010 48011 48012 48013 48014 48015 48016 48017 48018 48019 48020 48021 48022 48023 48024 48025 48026 48027 48028 48030 48029 48031 48032 48033 48034 59001 59002 59003 59004 59005 59006 59007 59008 59009 59010 59011 59026 59012 59013 59014 59015 59016 59017 59018 59019 59037 59020 59021 59022 59023 59024 59025 59027 59028 59029 59030 59031 59032 59033 59034 59035 59036 59038 59039 59040 59041 59042 60001 61001 62001 Canadian federal ridings (square grid)

And here is a multisquare of the Canadian provinces based on the above ridings.


In [8]:
import pandas as pd
df_prov = pd.read_csv('chorogrid/databases/canada_provinces.csv')

canada_prov_colors = [mycolors[x % len(mycolors)] for x in range(len(list(df_prov.province)))]

cg_prov = Chorogrid('chorogrid/databases/canada_provinces.csv', df_prov.province, canada_prov_colors, 'province')
cg_prov.set_title('Canadian provinces cartogram (square grid)', font_dict={'font-size': 19})
cg_prov.draw_multisquare(font_dict={'fill-opacity': 0}, 
                    spacing_dict={'margin_bottom': 250, 'cell_width': 16,
                                  'stroke_width': 1, 'stroke_color': '#000000'})
cg_prov.done(show=True)

# Known issue: we have to add a bottom margin of 250 to make this map visible, normally the height variable
# should take care of that without tweaking. It's because the added height from the contours is not added.


NL PE NS NB QC ON MB SK AB BC YT NT NU Canadian provinces cartogram (square grid)

Now we can overlay the borders from the provinces multisquare, setting the fill colors to 'none' (the string, not None the Python object), atop the ridings map.


In [9]:
import pandas as pd
df = pd.read_csv('chorogrid/databases/canada_federal_ridings.csv')
provinces = df.province.unique()
province2color = {}
for i, province in enumerate(provinces):
    province2color[province] = mycolors[i % len(mycolors)]
canada_riding_colors = [province2color[province] for province in list(df.province)]

cg_ridings = Chorogrid('chorogrid/databases/canada_federal_ridings.csv', list(df.district_code), 
                       canada_riding_colors, 'district_code')
cg_ridings.set_title('Canadian federal ridings (square grid)', font_dict={'font-size': 19})
cg_ridings.draw_squares(spacing_dict={'cell_width': 15, 'roundedness': 2},
                        font_dict={'fill-opacity': 0})

df_prov = pd.read_csv('chorogrid/databases/canada_provinces.csv')
canada_prov_colors = ['none' for x in range(len(df_prov.province))]

cg_prov = Chorogrid('chorogrid/databases/canada_provinces.csv', df_prov.province, canada_prov_colors, 'province')
cg_prov.draw_multisquare(font_dict={'fill-opacity': 0}, 
                    spacing_dict={'margin_bottom': 250, 'cell_width': 16,
                                  'stroke_width': 1, 'stroke_color': '#000000'})

cg_ridings.done_and_overlay(cg_prov, show=True)

# Known issue: overlay cell width must be set to 16, while ridings cell width is set to 15, because
# overlay stroke==1.


10001 10002 10003 10004 10005 10006 10007 11001 11002 11003 11004 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 24001 24002 24003 24004 24005 24006 24007 24020 24008 24009 24010 24011 24012 24015 24016 24017 24019 24021 24022 24023 24024 24025 24026 24027 24028 24029 24030 24031 24032 24033 24034 24035 24036 24037 24038 24039 24040 24042 24041 24043 24044 24045 24046 24065 24047 24048 24049 24050 24051 24052 24053 24054 24055 24014 24056 24057 24058 24059 24060 24061 24018 24062 24063 24064 24066 24067 24068 24069 24070 24071 24072 24073 24075 24013 24076 24074 24077 24078 35001 35002 35003 35004 35005 35006 35007 35008 35009 35010 35011 35012 35013 35014 35015 35016 35088 35017 35018 35019 35020 35021 35022 35023 35024 35025 35026 35027 35028 35029 35030 35031 35032 35033 35034 35035 35036 35037 35038 35039 35121 35040 35041 35042 35043 35044 35045 35046 35047 35048 35049 35050 35051 35052 35053 35054 35055 35056 35057 35058 35059 35060 35061 35062 35063 35064 35065 35066 35067 35068 35069 35070 35071 35072 35073 35076 35074 35075 35077 35078 35079 35080 35081 35082 35083 35084 35085 35086 35087 35089 35091 35092 35093 35094 35095 35096 35097 35098 35099 35100 35101 35102 35103 35104 35105 35106 35107 35108 35109 35090 35110 35111 35112 35113 35114 35115 35116 35117 35118 35119 35120 46001 46002 46003 46004 46005 46006 46007 46008 46009 46010 46011 46012 46013 46014 47001 47004 47002 47003 47005 47006 47007 47008 47009 47010 47011 47012 47013 47014 48001 48002 48003 48004 48005 48006 48007 48008 48009 48010 48011 48012 48013 48014 48015 48016 48017 48018 48019 48020 48021 48022 48023 48024 48025 48026 48027 48028 48030 48029 48031 48032 48033 48034 59001 59002 59003 59004 59005 59006 59007 59008 59009 59010 59011 59026 59012 59013 59014 59015 59016 59017 59018 59019 59037 59020 59021 59022 59023 59024 59025 59027 59028 59029 59030 59031 59032 59033 59034 59035 59036 59038 59039 59040 59041 59042 60001 61001 62001 Canadian federal ridings (square grid) NL PE NS NB QC ON MB SK AB BC YT NT NU

And here's the square grid with the transposed 2011 elections results


In [33]:
df_elxn = pd.read_csv('chorogrid/sample_data/TRANSPOSITION_338FED.csv', skiprows=4, encoding='latin-1', index_col=False)
df_elxn = df_elxn[['2013 FED Number', 'Conservative votes', 'NDP-New Democratic Party votes', 'Liberal votes', 'Bloc Québécois votes', 'Green Party votes']]
df_elxn.columns = ['FED', 'Con', 'NDP', 'Lib', 'BQ', 'Green']
df_elxn = pd.DataFrame(df_elxn.groupby('FED').sum())
df_elxn['winner'] = ''
for idx, row in df_elxn.iterrows():
    rowlist = list(row)[:5]
    winner = ['Conservative',
              'NDP',
              'Liberal',
              'Bloc Québécois',
              'Green'][rowlist.index(max(rowlist))]
    df_elxn.loc[idx, 'winner'] = winner
    
winner2colors = {'Conservative': '#3333aa',
                 'NDP': '#bb8811',
                 'Liberal': '#aa3333',
                 'Bloc Québécois': '#11bbbb',
                 'Green': '#33aa33'}

df = pd.read_csv('chorogrid/databases/canada_federal_ridings.csv')
canada_riding_colors = []
for idx, row in df.iterrows():
    fed = row.district_code
    winner = df_elxn.winner.ix[fed]
    canada_riding_colors.append(winner2colors[winner])
    
parties = list(winner2colors.keys())
parties.sort()
parties.reverse()
partycolors = [winner2colors[k] for k in parties]

In [38]:
cg_ridings = Chorogrid('chorogrid/databases/canada_federal_ridings.csv', list(df.district_code), 
                       canada_riding_colors, 'district_code')
cg_ridings.set_title('Canadian federal ridings (square grid)', font_dict={'font-size': 19})
cg_ridings.set_legend(partycolors, parties)
cg_ridings.draw_squares(spacing_dict={'cell_width': 15, 'roundedness': 2, 'legend_offset': (-120,-70)},
                        font_dict={'fill-opacity': 0})
cg_ridings.done(show=True)


48001 48007 48012 48022 48034 48004 48008 48010 48020 48021 48005 48011 48018 48024 48026 48029 48031 48033 48003 48006 48009 48014 48015 48023 48028 48030 48002 48013 48016 48017 48019 48025 48027 48032 59009 59010 59018 59026 59027 59041 59025 59031 59037 59039 59011 59028 59034 59036 59040 59019 59030 59033 59038 59042 59003 59007 59035 59002 59008 59012 59016 59001 59021 59022 59023 59032 59004 59005 59006 59014 59017 59013 59015 59020 59024 59029 46001 46002 46007 46004 46011 46013 46014 46003 46005 46009 46012 46006 46008 46010 13003 13005 13010 13001 13006 13007 13008 13002 13004 13009 10004 10005 10003 10002 10001 10006 10007 12011 12006 12009 12003 12005 12007 12002 12004 12008 12001 12010 61001 62001 35042 35046 35091 35105 35117 35052 35083 35092 35106 35107 35112 35113 35116 35002 35008 35014 35026 35032 35040 35045 35048 35053 35103 35010 35011 35012 35017 35022 35051 35057 35080 35099 35100 35005 35009 35016 35025 35043 35047 35058 35062 35069 35111 35004 35013 35015 35029 35063 35065 35073 35082 35104 35121 35003 35030 35035 35054 35060 35072 35087 35118 35119 35120 35020 35027 35033 35034 35056 35059 35061 35070 35084 35115 35018 35023 35028 35037 35038 35049 35055 35086 35090 35021 35024 35036 35039 35041 35078 35081 35085 35093 35001 35031 35064 35068 35071 35079 35096 35101 35110 35114 35019 35044 35067 35075 35076 35077 35094 35097 35108 35109 35006 35007 35066 35074 35089 35095 35102 35050 35088 35098 11003 11004 11002 11001 24002 24027 24030 24057 24005 24013 24031 24035 24038 24029 24048 24050 24063 24033 24040 24056 24062 24065 24075 24003 24004 24012 24055 24068 24076 24078 24009 24015 24036 24052 24064 24069 24070 24074 24001 24021 24028 24032 24037 24053 24054 24058 24060 24071 24014 24019 24022 24025 24034 24039 24042 24045 24046 24049 24067 24077 24008 24011 24017 24020 24024 24043 24044 24059 24066 24010 24016 24018 24041 24051 24061 24072 24073 24006 24007 24023 24047 24026 47001 47002 47004 47010 47007 47011 47012 47003 47005 47006 47009 47008 47013 47014 60001 Bloc Québécois Conservative Green Liberal NDP Canadian federal ridings (square grid)

In [ ]: