Generate Map

Class that generates the data map
# TODO - do a need a state class that tracks the state of different website objects to help with
# updating etc. 
# TODO - not even state, should it be an object that contains everythin to track. Execpt if I am patching,
# then the tracking in mem is unessary, so better to just track necesary values like: last changes card etc.

Load Data

sol_geo = SolomonGeo.load_pickle("/testData/")

Build the Cloreopath Map

go.

z_vals = sol_geo.get_census(geo_filter = 'Province', var = 'Key Statistics', 
                                                 measure = 'Total Households').values
np.min(z_vals)
688
fig = define_map(sol_geo)
print(fig['data'][0]['zmin'])
688

Election Maps

Slightly different as they have less geographies and colour based on winning party

sol_geo.elec_wide.head()
Type Year Geo loc_name 0 1 2 Winning Party
0 National Parliament 2024 Constituency Auki-Langalanga Cooper Wale (SID) - 4314 (66.2%) David Filia (OUR) - 1348 (20.7%) Talauburi Anisi (KAD) - 488 (7.5%) SID
1 National Parliament 2024 Constituency Baegu-Asifola Tagini Makario (OUR) - 2391 (37.4%) Celsus Talifilu (U4C) - 2147 (33.6%) Douglas Buga (SIP) - 1009 (15.8%) OUR
2 National Parliament 2024 Constituency Central Guadalcanal Shanel Agovaka (OUR) - 3454 (43.1%) Manengelea Rex (IND) - 1592 (19.8%) Denson Denni (KAD) - 1381 (17.2%) OUR
3 National Parliament 2024 Constituency Central Honiara Darcy Lilo (SIP) - 8223 (63.4%) Alfred Efona (UP) - 3632 (28.0%) Francis Idu (OUR) - 669 (5.2%) SIP
4 National Parliament 2024 Constituency Central Kwara'ae Ricky Fuo'o (UP) - 5208 (47.9%) Jackson Fiulaua (OUR) - 1831 (16.8%) Young Wate (IND) - 1537 (14.1%) UP
sol_geo.elec_wide["Winning Party"].unique()
array(['SID', 'OUR', 'SIP', 'UP', 'IND', 'PFP', 'U4C', 'KAD', 'DAP'],
      dtype=object)
sol_geo.elec["Party"].unique()
array(['UP', 'PLD', 'KAD', 'OUR', 'SID', 'IND', 'SIP', 'U4C', 'PAP',
       'PFP', 'DAP', 'NTP', 'GPS'], dtype=object)

TODO

I need to make a unique color for each party, then colorscale will need to have all as an option. Probably a dictionary is better. Use the color brewer colors plus maybe another colour like black https://colorbrewer2.org/#type=qualitative&scheme=Set3&n=12


source

election_map

def election_map(
    sol_df:SolomonGeo, # Solomon geo object containing census data to input into map
)->Figure: # Returns a graph object figure

Creates and returns a chloreopath map for election

#election_map(sol_geo).show()
election_map(sol_geo)['data'][0]['colorscale']
((0.0, '#8dd3c7'), (1.0, '#8dd3c7'))

Create a bar graph to display current data

gen_bar_plot(sol_geo, 'Ward', "Main source of household income in last 12 months", 'Wages Salary', ['Cruz', 'Vavaea'], 'Proportion')

Bar Plot for Elections Data

Example plot for Auki-Langalanga

df = sol_geo.elec
loc = 'Auki-Langalanga'

df.loc[df['loc_name'] == loc, 'candParty'].values
array(['Joseph Waleanisia (UP)', 'Obadiah Koti (PLD)',
       'Talauburi Anisi (KAD)', 'David Filia (OUR)', 'Cooper Wale (SID)'],
      dtype=object)
fig = go.Figure()
measures = list(df.columns)
fig.add_trace(go.Bar(
    x = df.loc[df['loc_name'] == loc, 'Candidate'].values,
    y = df.loc[df['loc_name'] == loc, 'Total'].values,
    name = loc,
    marker = dict(color = list(map(lambda y: sol_geo.colormap[y], df.loc[df['loc_name'] == loc, 'Party'].values))),
    hovertemplate = '%{x} <extra>%{y}</extra>',
    text = df.loc[df['loc_name'] == loc, 'Total'].values,
    textposition='auto',
))
fig.update_layout(barmode='group', xaxis_tickangle=-45, title_text="Title",
                   xaxis={'categoryorder':'total descending'}, )
fig.update_traces(textfont_size=12, textangle=0, textposition="outside", cliponaxis=False)

source

election_bar_plot

def election_bar_plot(
    sol_geo:SolomonGeo, # Solomon geo object containing census data to input into map
    geo_filter:str='Constituency', # The desired aggregation of the geography
    year:int=2024, # The year of the elections data
    election:str='National Parliament', # The type of election.
    location:str='Auki-Langalanga', # Desired location within aggregation
    type_filter:str='Total', # The type of data, eitehr Total of Proportion
)->Figure: # Returns a graph object figure of a barplot

Create a bar plot that show the census selected election data

election_bar_plot(sol_geo, type_filter = 'Proportion')

Create Data Tables

Census Data Table

A method that creates data tables for census


source

gen_census_grid

def gen_census_grid(
    sol_geo:SolomonGeo, # Solomon geo object containing census data to input into map
    geo_filter:str, # The desired aggregation of the geography
    variable:str, # The variable to use to create the bar plot
    measure:str, # The measure to highlight on the bar graph
    locations:[<class 'str'>]=None, # Desired location within aggregation
    type_filter:str='Total', # The type aggregartion
    grid_rows:int=10, # The number of rows to display
)->AgGrid: # Returns a graph object figure of a barplot

Creates a basic data table using dash grid

gen_census_grid(sol_geo, 'Province', "Main source of household income in last 12 months", 'Wages Salary')
AgGrid(id='dash-grid', columnDefs=[{'field': 'Province', 'headerName': 'Province', 'filter': True, 'lockPinned': True, 'cellClass': 'lock-pinned'}, {'field': 'No income', 'headerName': 'No income'}, {'field': 'Wages Salary', 'headerName': 'Wages Salary'}, {'field': 'Own business', 'headerName': 'Own business'}, {'field': 'Sale fish crop craft', 'headerName': 'Sale fish crop craft'}, {'field': 'Land lease', 'headerName': 'Land lease'}, {'field': 'House rent', 'headerName': 'House rent'}, {'field': 'Remittances', 'headerName': 'Remittances'}, {'field': 'Other source', 'headerName': 'Other source'}], columnSize='sizeToFit', csvExportParams={'fileName': 'Solomons 2009 Census Data Main source of household income in last 12 months by Province - Total.csv'}, dashGridOptions={'pagination': True, 'domLayout': 'autoHeight', 'paginationPageSize': 10, 'wrapHeaderText': True, 'autoHeaderHeight': True}, defaultColDef={'resizable': True, 'sortable': True, 'minWidth': 100}, rowData=[{'Province': 'Central', 'No income': 66.0, 'Wages Salary': 665.0, 'Own business': 373.0, 'Sale fish crop craft': 2518.0, 'Land lease': 1.0, 'House rent': 5.0, 'Remittances': 88.0, 'Other source': 1189.0}, {'Province': 'Choiseul', 'No income': 88.0, 'Wages Salary': 892.0, 'Own business': 206.0, 'Sale fish crop craft': 2443.0, 'Land lease': 6.0, 'House rent': 16.0, 'Remittances': 206.0, 'Other source': 855.0}, {'Province': 'Guadalcanal', 'No income': 538.0, 'Wages Salary': 3978.0, 'Own business': 868.0, 'Sale fish crop craft': 7702.0, 'Land lease': 20.0, 'House rent': 102.0, 'Remittances': 182.0, 'Other source': 3773.0}, {'Province': 'Honiara', 'No income': 75.0, 'Wages Salary': 6984.0, 'Own business': 783.0, 'Sale fish crop craft': 393.0, 'Land lease': 54.0, 'House rent': 179.0, 'Remittances': 48.0, 'Other source': 465.0}, {'Province': 'Isabel', 'No income': 92.0, 'Wages Salary': 907.0, 'Own business': 310.0, 'Sale fish crop craft': 2900.0, 'Land lease': 4.0, 'House rent': 18.0, 'Remittances': 174.0, 'Other source': 738.0}, {'Province': 'Makira-Ulawa', 'No income': 315.0, 'Wages Salary': 1007.0, 'Own business': 459.0, 'Sale fish crop craft': 3293.0, 'Land lease': 14.0, 'House rent': 28.0, 'Remittances': 90.0, 'Other source': 1967.0}, {'Province': 'Malaita', 'No income': 1404.0, 'Wages Salary': 2942.0, 'Own business': 1290.0, 'Sale fish crop craft': 11075.0, 'Land lease': 15.0, 'House rent': 154.0, 'Remittances': 584.0, 'Other source': 6957.0}, {'Province': 'Rennell-Bell', 'No income': 114.0, 'Wages Salary': 147.0, 'Own business': 40.0, 'Sale fish crop craft': 244.0, 'Land lease': 1.0, 'House rent': 13.0, 'Remittances': 82.0, 'Other source': 47.0}, {'Province': 'Temotu', 'No income': 159.0, 'Wages Salary': 612.0, 'Own business': 166.0, 'Sale fish crop craft': 2505.0, 'Land lease': 10.0, 'House rent': 14.0, 'Remittances': 120.0, 'Other source': 717.0}, {'Province': 'Western', 'No income': 182.0, 'Wages Salary': 3732.0, 'Own business': 618.0, 'Sale fish crop craft': 7518.0, 'Land lease': 8.0, 'House rent': 48.0, 'Remittances': 410.0, 'Other source': 1246.0}], style={'height': None})

Create a Population Grid


source

gen_pop_grid

def gen_pop_grid(
    sol_geo:SolomonGeo, # Solomon geo object containing census data to input into map
    years:str, # Selected data years
    variable:str, # The variable to use to create the bar plot
    measure:str, # The measure to highlight on the bar graph
    geo_filter:str='Province', # The desired aggregation of the geography
    locations:[<class 'str'>]=None, # Desired location within aggregation
    type_filter:str='Total', # The type aggregartion
    grid_rows:int=10, # The number of rows to display
)->AgGrid: # Returns a graph object figure of a barplot

Creates a basic data table using dash grid

gen_pop_grid(sol_geo, [2023, 2024, 2025], 'Population', 'Total',)
AgGrid(id='dash-grid', columnDefs=[{'field': 'Province', 'headerName': 'Province', 'filter': True, 'lockPinned': True, 'cellClass': 'lock-pinned'}, {'field': 'Year', 'headerName': 'Year', 'filter': True, 'lockPinned': True, 'cellClass': 'lock-pinned'}, {'field': '0-4', 'headerName': '0-4'}, {'field': '5-9', 'headerName': '5-9'}, {'field': '10-14', 'headerName': '10-14'}, {'field': '15-19', 'headerName': '15-19'}, {'field': '20-24', 'headerName': '20-24'}, {'field': '25-29', 'headerName': '25-29'}, {'field': '30-34', 'headerName': '30-34'}, {'field': '35-39', 'headerName': '35-39'}, {'field': '40-44', 'headerName': '40-44'}, {'field': '45-49', 'headerName': '45-49'}, {'field': '50-54', 'headerName': '50-54'}, {'field': '55-59', 'headerName': '55-59'}, {'field': '60-64', 'headerName': '60-64'}, {'field': '65-69', 'headerName': '65-69'}, {'field': '70-74', 'headerName': '70-74'}, {'field': '75-79', 'headerName': '75-79'}, {'field': '80+', 'headerName': '80+'}], columnSize='sizeToFit', csvExportParams={'fileName': 'Solomons 2009 Population Projections for Population Population by Province - Total.csv'}, dashGridOptions={'pagination': True, 'domLayout': 'autoHeight', 'paginationPageSize': 10, 'wrapHeaderText': True, 'autoHeaderHeight': True}, defaultColDef={'resizable': True, 'sortable': True, 'minWidth': 100}, rowData=[{'Year': 2023, 'Province': 'Central', '0-4': 3621.0, '5-9': 3642.0, '10-14': 3915.0, '15-19': 4036.0, '20-24': 3534.0, '25-29': 2622.0, '30-34': 1920.0, '35-39': 1740.0, '40-44': 1830.0, '45-49': 1786.0, '50-54': 1610.0, '55-59': 1073.0, '60-64': 891.0, '65-69': 597.0, '70-74': 483.0, '75-79': 321.0, '80+': 296.0}, {'Year': 2024, 'Province': 'Central', '0-4': 3641.0, '5-9': 3603.0, '10-14': 3861.0, '15-19': 4019.0, '20-24': 3656.0, '25-29': 2773.0, '30-34': 1995.0, '35-39': 1719.0, '40-44': 1811.0, '45-49': 1776.0, '50-54': 1689.0, '55-59': 1127.0, '60-64': 933.0, '65-69': 620.0, '70-74': 493.0, '75-79': 334.0, '80+': 309.0}, {'Year': 2025, 'Province': 'Central', '0-4': 3671.0, '5-9': 3576.0, '10-14': 3788.0, '15-19': 4001.0, '20-24': 3757.0, '25-29': 2928.0, '30-34': 2091.0, '35-39': 1716.0, '40-44': 1779.0, '45-49': 1773.0, '50-54': 1732.0, '55-59': 1212.0, '60-64': 958.0, '65-69': 659.0, '70-74': 499.0, '75-79': 348.0, '80+': 322.0}, {'Year': 2023, 'Province': 'Choiseul', '0-4': 4900.0, '5-9': 4586.0, '10-14': 4396.0, '15-19': 4266.0, '20-24': 3885.0, '25-29': 3128.0, '30-34': 2539.0, '35-39': 2187.0, '40-44': 2007.0, '45-49': 1851.0, '50-54': 1668.0, '55-59': 1208.0, '60-64': 937.0, '65-69': 641.0, '70-74': 499.0, '75-79': 309.0, '80+': 330.0}, {'Year': 2024, 'Province': 'Choiseul', '0-4': 4973.0, '5-9': 4630.0, '10-14': 4458.0, '15-19': 4258.0, '20-24': 4013.0, '25-29': 3274.0, '30-34': 2640.0, '35-39': 2238.0, '40-44': 2040.0, '45-49': 1865.0, '50-54': 1735.0, '55-59': 1268.0, '60-64': 989.0, '65-69': 665.0, '70-74': 522.0, '75-79': 313.0, '80+': 345.0}, {'Year': 2025, 'Province': 'Choiseul', '0-4': 5048.0, '5-9': 4682.0, '10-14': 4479.0, '15-19': 4289.0, '20-24': 4117.0, '25-29': 3429.0, '30-34': 2750.0, '35-39': 2299.0, '40-44': 2071.0, '45-49': 1888.0, '50-54': 1777.0, '55-59': 1346.0, '60-64': 1032.0, '65-69': 704.0, '70-74': 536.0, '75-79': 328.0, '80+': 355.0}, {'Year': 2023, 'Province': 'Guadalcanal', '0-4': 21745.0, '5-9': 20158.0, '10-14': 17946.0, '15-19': 16342.0, '20-24': 15215.0, '25-29': 14197.0, '30-34': 13723.0, '35-39': 13159.0, '40-44': 10683.0, '45-49': 8749.0, '50-54': 6879.0, '55-59': 4715.0, '60-64': 3450.0, '65-69': 2140.0, '70-74': 1608.0, '75-79': 941.0, '80+': 870.0}, {'Year': 2024, 'Province': 'Guadalcanal', '0-4': 22087.0, '5-9': 20561.0, '10-14': 18484.0, '15-19': 16701.0, '20-24': 15766.0, '25-29': 14668.0, '30-34': 13976.0, '35-39': 13660.0, '40-44': 11240.0, '45-49': 9147.0, '50-54': 7337.0, '55-59': 5032.0, '60-64': 3717.0, '65-69': 2273.0, '70-74': 1697.0, '75-79': 980.0, '80+': 912.0}, {'Year': 2025, 'Province': 'Guadalcanal', '0-4': 22419.0, '5-9': 20948.0, '10-14': 18986.0, '15-19': 17102.0, '20-24': 16290.0, '25-29': 15166.0, '30-34': 14301.0, '35-39': 14036.0, '40-44': 11849.0, '45-49': 9569.0, '50-54': 7749.0, '55-59': 5425.0, '60-64': 3947.0, '65-69': 2466.0, '70-74': 1760.0, '75-79': 1044.0, '80+': 947.0}, {'Year': 2023, 'Province': 'Honiara', '0-4': 8666.0, '5-9': 9207.0, '10-14': 9041.0, '15-19': 8060.0, '20-24': 7380.0, '25-29': 7291.0, '30-34': 8878.0, '35-39': 10220.0, '40-44': 7840.0, '45-49': 5991.0, '50-54': 4628.0, '55-59': 3193.0, '60-64': 2359.0, '65-69': 1509.0, '70-74': 943.0, '75-79': 507.0, '80+': 313.0}, {'Year': 2024, 'Province': 'Honiara', '0-4': 8535.0, '5-9': 9146.0, '10-14': 9172.0, '15-19': 8285.0, '20-24': 7595.0, '25-29': 7252.0, '30-34': 8475.0, '35-39': 10381.0, '40-44': 8319.0, '45-49': 6300.0, '50-54': 4918.0, '55-59': 3392.0, '60-64': 2507.0, '65-69': 1620.0, '70-74': 1014.0, '75-79': 547.0, '80+': 343.0}, {'Year': 2025, 'Province': 'Honiara', '0-4': 8404.0, '5-9': 9065.0, '10-14': 9241.0, '15-19': 8536.0, '20-24': 7802.0, '25-29': 7291.0, '30-34': 8159.0, '35-39': 10294.0, '40-44': 8849.0, '45-49': 6643.0, '50-54': 5182.0, '55-59': 3636.0, '60-64': 2642.0, '65-69': 1746.0, '70-74': 1085.0, '75-79': 593.0, '80+': 374.0}, {'Year': 2023, 'Province': 'Isabel', '0-4': 4165.0, '5-9': 4041.0, '10-14': 4026.0, '15-19': 4005.0, '20-24': 3680.0, '25-29': 2958.0, '30-34': 2468.0, '35-39': 2128.0, '40-44': 2054.0, '45-49': 1985.0, '50-54': 1666.0, '55-59': 1131.0, '60-64': 993.0, '65-69': 764.0, '70-74': 590.0, '75-79': 379.0, '80+': 377.0}, {'Year': 2024, 'Province': 'Isabel', '0-4': 4203.0, '5-9': 4051.0, '10-14': 4047.0, '15-19': 3992.0, '20-24': 3804.0, '25-29': 3087.0, '30-34': 2562.0, '35-39': 2171.0, '40-44': 2059.0, '45-49': 2004.0, '50-54': 1764.0, '55-59': 1185.0, '60-64': 1020.0, '65-69': 786.0, '70-74': 613.0, '75-79': 394.0, '80+': 392.0}, {'Year': 2025, 'Province': 'Isabel', '0-4': 4244.0, '5-9': 4068.0, '10-14': 4038.0, '15-19': 4002.0, '20-24': 3900.0, '25-29': 3232.0, '30-34': 2657.0, '35-39': 2228.0, '40-44': 2067.0, '45-49': 2019.0, '50-54': 1838.0, '55-59': 1271.0, '60-64': 1036.0, '65-69': 816.0, '70-74': 632.0, '75-79': 413.0, '80+': 407.0}, {'Year': 2023, 'Province': 'Makira-Ulawa', '0-4': 7179.0, '5-9': 7037.0, '10-14': 7244.0, '15-19': 6960.0, '20-24': 5670.0, '25-29': 4277.0, '30-34': 3355.0, '35-39': 3440.0, '40-44': 3220.0, '45-49': 2842.0, '50-54': 2267.0, '55-59': 1512.0, '60-64': 1238.0, '65-69': 832.0, '70-74': 658.0, '75-79': 417.0, '80+': 398.0}, {'Year': 2024, 'Province': 'Makira-Ulawa', '0-4': 7242.0, '5-9': 7021.0, '10-14': 7177.0, '15-19': 7117.0, '20-24': 5929.0, '25-29': 4533.0, '30-34': 3405.0, '35-39': 3428.0, '40-44': 3263.0, '45-49': 2910.0, '50-54': 2410.0, '55-59': 1589.0, '60-64': 1297.0, '65-69': 864.0, '70-74': 679.0, '75-79': 427.0, '80+': 414.0}, {'Year': 2025, 'Province': 'Makira-Ulawa', '0-4': 7321.0, '5-9': 7021.0, '10-14': 7120.0, '15-19': 7209.0, '20-24': 6185.0, '25-29': 4788.0, '30-34': 3525.0, '35-39': 3390.0, '40-44': 3302.0, '45-49': 2977.0, '50-54': 2526.0, '55-59': 1706.0, '60-64': 1335.0, '65-69': 916.0, '70-74': 691.0, '75-79': 446.0, '80+': 427.0}, {'Year': 2023, 'Province': 'Malaita', '0-4': 18990.0, '5-9': 18896.0, '10-14': 20187.0, '15-19': 20945.0, '20-24': 18277.0, '25-29': 13286.0, '30-34': 9337.0, '35-39': 7805.0, '40-44': 7425.0, '45-49': 6991.0, '50-54': 5924.0, '55-59': 4453.0, '60-64': 3759.0, '65-69': 2804.0, '70-74': 2244.0, '75-79': 1627.0, '80+': 1394.0}, {'Year': 2024, 'Province': 'Malaita', '0-4': 19039.0, '5-9': 18690.0, '10-14': 19891.0, '15-19': 20718.0, '20-24': 18748.0, '25-29': 13942.0, '30-34': 9648.0, '35-39': 7769.0, '40-44': 7338.0, '45-49': 7010.0, '50-54': 6134.0, '55-59': 4578.0, '60-64': 3859.0, '65-69': 2871.0, '70-74': 2255.0, '75-79': 1667.0, '80+': 1453.0}, {'Year': 2025, 'Province': 'Malaita', '0-4': 19122.0, '5-9': 18543.0, '10-14': 19503.0, '15-19': 20502.0, '20-24': 19118.0, '25-29': 14609.0, '30-34': 10052.0, '35-39': 7776.0, '40-44': 7246.0, '45-49': 7006.0, '50-54': 6295.0, '55-59': 4766.0, '60-64': 3924.0, '65-69': 2967.0, '70-74': 2267.0, '75-79': 1696.0, '80+': 1516.0}, {'Year': 2023, 'Province': 'Rennell-Bell', '0-4': 566.0, '5-9': 491.0, '10-14': 424.0, '15-19': 428.0, '20-24': 444.0, '25-29': 449.0, '30-34': 299.0, '35-39': 264.0, '40-44': 189.0, '45-49': 227.0, '50-54': 172.0, '55-59': 127.0, '60-64': 132.0, '65-69': 126.0, '70-74': 113.0, '75-79': 65.0, '80+': 67.0}, {'Year': 2024, 'Province': 'Rennell-Bell', '0-4': 581.0, '5-9': 506.0, '10-14': 441.0, '15-19': 421.0, '20-24': 437.0, '25-29': 473.0, '30-34': 317.0, '35-39': 282.0, '40-44': 190.0, '45-49': 229.0, '50-54': 184.0, '55-59': 130.0, '60-64': 131.0, '65-69': 124.0, '70-74': 116.0, '75-79': 72.0, '80+': 68.0}, {'Year': 2025, 'Province': 'Rennell-Bell', '0-4': 595.0, '5-9': 521.0, '10-14': 453.0, '15-19': 420.0, '20-24': 435.0, '25-29': 483.0, '30-34': 346.0, '35-39': 293.0, '40-44': 201.0, '45-49': 223.0, '50-54': 197.0, '55-59': 137.0, '60-64': 129.0, '65-69': 124.0, '70-74': 117.0, '75-79': 78.0, '80+': 70.0}, {'Year': 2023, 'Province': 'Temotu', '0-4': 2686.0, '5-9': 2674.0, '10-14': 2813.0, '15-19': 3071.0, '20-24': 2905.0, '25-29': 2072.0, '30-34': 1578.0, '35-39': 1250.0, '40-44': 1220.0, '45-49': 1168.0, '50-54': 1197.0, '55-59': 910.0, '60-64': 765.0, '65-69': 586.0, '70-74': 460.0, '75-79': 269.0, '80+': 315.0}, {'Year': 2024, 'Province': 'Temotu', '0-4': 2697.0, '5-9': 2650.0, '10-14': 2805.0, '15-19': 2959.0, '20-24': 2996.0, '25-29': 2179.0, '30-34': 1646.0, '35-39': 1259.0, '40-44': 1221.0, '45-49': 1144.0, '50-54': 1219.0, '55-59': 941.0, '60-64': 789.0, '65-69': 598.0, '70-74': 479.0, '75-79': 283.0, '80+': 317.0}, {'Year': 2025, 'Province': 'Temotu', '0-4': 2710.0, '5-9': 2636.0, '10-14': 2756.0, '15-19': 2891.0, '20-24': 3043.0, '25-29': 2309.0, '30-34': 1709.0, '35-39': 1288.0, '40-44': 1210.0, '45-49': 1136.0, '50-54': 1215.0, '55-59': 986.0, '60-64': 806.0, '65-69': 617.0, '70-74': 490.0, '75-79': 301.0, '80+': 319.0}, {'Year': 2023, 'Province': 'Western', '0-4': 11762.0, '5-9': 11511.0, '10-14': 11679.0, '15-19': 11368.0, '20-24': 10110.0, '25-29': 8167.0, '30-34': 6990.0, '35-39': 5802.0, '40-44': 5338.0, '45-49': 4928.0, '50-54': 4599.0, '55-59': 3756.0, '60-64': 2749.0, '65-69': 1874.0, '70-74': 1368.0, '75-79': 889.0, '80+': 833.0}, {'Year': 2024, 'Province': 'Western', '0-4': 11834.0, '5-9': 11500.0, '10-14': 11631.0, '15-19': 11449.0, '20-24': 10408.0, '25-29': 8406.0, '30-34': 7198.0, '35-39': 5919.0, '40-44': 5398.0, '45-49': 4953.0, '50-54': 4678.0, '55-59': 3908.0, '60-64': 2914.0, '65-69': 1965.0, '70-74': 1420.0, '75-79': 921.0, '80+': 865.0}, {'Year': 2025, 'Province': 'Western', '0-4': 11916.0, '5-9': 11508.0, '10-14': 11564.0, '15-19': 11520.0, '20-24': 10650.0, '25-29': 8704.0, '30-34': 7373.0, '35-39': 6083.0, '40-44': 5447.0, '45-49': 4995.0, '50-54': 4729.0, '55-59': 4054.0, '60-64': 3076.0, '65-69': 2080.0, '70-74': 1468.0, '75-79': 959.0, '80+': 897.0}], style={'height': None})

dashGridOptions={‘pagination’: True, ‘domLayout’: ‘autoHeight’, ‘paginationPageSize’: 10},

Create KPI

The kpi card is useful for displaying a particular value as a standout kpi

# Build and test a card
gen_kpi(sol_geo, 2022, 'Population', 'Total', ["0-4"])
(Markdown('# 83,808'), Markdown('total persons in current selection'))

Create function to make dropdowns


source

gen_dd

def gen_dd(
    location_list:[<class 'str'>], # a list of locations
    id:str, # Id of the dropdown
    place_holder:str=None, # a placeholder message to display
    val:str=None, # The starting value of the dropdown
    clear:bool=False, # pick whether the ]
    height:int=35, # height of the dropdown text
    multi:bool=False, # Is the dropdown multi select
)->Dropdown: # Returns a dropdown

Create the location dropdown from given list

Create Population Pyramid

For use to demonstrate the population pyramid of solomon islands. It should highlight age groups based on selection


source

gen_pyramid

def gen_pyramid(
    sol_geo:SolomonGeo, # Solomon geo object containing census data to input into map
    geo_filter:str, # The desired aggregation of the geography
    year:str, # Selected year to display on the graph
    variable:str='Population', # The variable to use to create the bar plot
    locations:[<class 'str'>]=[], # Desired location within aggregation
    type_filter:str='Total', # The type aggregartion
    ages:[<class 'str'>]=[], # Currenly selected ages for highlighting
)->Figure: # Returns a population pyramid and it's title

Create a population pyramid of selected population data

gen_pyramid(sol_geo, geo_filter = 'Province', year = 2024, variable = "Population", locations = ['Western'], type_filter = "Proportion")

Testing

# TODO implementing testing, everything should at least be run here and execute and be displayed