def test_timedynamic_geo_json(): """ tests folium.plugins.TimeSliderChoropleth """ import geopandas as gpd assert 'naturalearth_lowres' in gpd.datasets.available datapath = gpd.datasets.get_path('naturalearth_lowres') gdf = gpd.read_file(datapath) n_periods = 3 dt_index = pd.date_range('2016-1-1', periods=n_periods, freq='M').strftime('%s') styledata = {} for country in gdf.index: pdf = pd.DataFrame( {'color': np.random.normal(size=n_periods), 'opacity': np.random.normal(size=n_periods)}, index=dt_index) styledata[country] = pdf.cumsum() max_color, min_color = 0, 0 for country, data in styledata.items(): max_color = max(max_color, data['color'].max()) min_color = min(max_color, data['color'].min()) cmap = linear.PuRd_09.scale(min_color, max_color) # Define function to normalize column into range [0,1] def norm(col): return (col - col.min())/(col.max()-col.min()) for country, data in styledata.items(): data['color'] = data['color'].apply(cmap) data['opacity'] = norm(data['opacity']) styledict = {str(country): data.to_dict(orient='index') for country, data in styledata.items()} m = folium.Map((0, 0), tiles='Stamen Watercolor', zoom_start=2) time_slider_choropleth = TimeSliderChoropleth( gdf.to_json(), styledict ) time_slider_choropleth.add_to(m) rendered = time_slider_choropleth._template.module.script(time_slider_choropleth) m._repr_html_() out = m._parent.render() assert '<script src="https://d3js.org/d3.v4.min.js"></script>' in out # We verify that data has been inserted correctly expected_timestamps = """var timestamps = ["1454198400", "1456704000", "1459382400"];""" # noqa assert expected_timestamps.split(';')[0].strip() == rendered.split(';')[0].strip() expected_styledict = json.dumps(styledict, sort_keys=True, indent=2) assert expected_styledict in rendered
def test_timedynamic_geo_json(): """ tests folium.plugins.TimeSliderChoropleth """ import geopandas as gpd assert 'naturalearth_lowres' in gpd.datasets.available datapath = gpd.datasets.get_path('naturalearth_lowres') gdf = gpd.read_file(datapath) n_periods = 3 dt_index = pd.date_range('2016-1-1', periods=n_periods, freq='M').strftime('%s') styledata = {} for country in gdf.index: pdf = pd.DataFrame( {'color': np.random.normal(size=n_periods), 'opacity': np.random.normal(size=n_periods)}, index=dt_index) styledata[country] = pdf.cumsum() max_color, min_color = 0, 0 for country, data in styledata.items(): max_color = max(max_color, data['color'].max()) min_color = min(max_color, data['color'].min()) cmap = linear.PuRd_09.scale(min_color, max_color) # Define function to normalize column into range [0,1] def norm(col): return (col - col.min())/(col.max()-col.min()) for country, data in styledata.items(): data['color'] = data['color'].apply(cmap) data['opacity'] = norm(data['opacity']) styledict = {str(country): data.to_dict(orient='index') for country, data in styledata.items()} m = folium.Map((0, 0), tiles='Stamen Watercolor', zoom_start=2) time_slider_choropleth = TimeSliderChoropleth( gdf.to_json(), styledict ) time_slider_choropleth.add_to(m) rendered = time_slider_choropleth._template.module.script(time_slider_choropleth) m._repr_html_() out = m._parent.render() assert '<script src="https://d3js.org/d3.v4.min.js"></script>' in out # We verify that data has been inserted correctly expected_timestamps = """var timestamps = ["1454198400", "1456704000", "1459382400"];""" # noqa assert expected_timestamps.split(';')[0].strip() == rendered.split(';')[0].strip() expected_styledict = json.dumps(styledict, sort_keys=True, indent=2) assert expected_styledict in rendered
def time_slider_choropleth(gpolys, values, dates, mini=None, maxi=None, dstr_format='%Y-%m-%d', color_per_day=False): """ :param gpolys: GeoDataFrame with the shape :param values: {index_of_gpolys: [values per day]} :param dates: list of dates (str) as the same format as dstr_format :param mini: min value across all values, if None, min(values) is used :param maxi: max value across all values, if None, max(values) is used :param dstr_format: format of dates str :param color_per_day: whether the color percentage/min/max is computed for each day. Default False :return: a layer that can call add_to(folium_map) """ from folium.plugins import TimeSliderChoropleth from branca.colormap import linear cmap = linear.Reds_09.scale() dates = [str(int(datetime.datetime.strptime(t, dstr_format).timestamp())) for t in dates] values = pd.DataFrame(values) assert len(dates) == values.shape[0] if maxi is None: maxi = values.max().max() if mini is None: mini = values.min().min() if color_per_day: colors = values.apply(lambda x: (x - x.min()) / (x.max() - x.min()), axis=1).applymap(cmap) else: colors = values.applymap(lambda x: (x - mini) / (maxi - mini)).applymap(cmap) colors.index = dates styledict = {} for i in colors: styledict[str(i)] = {d: {'color': c, 'opacity': 0.8} for d, c in colors[i].iteritems()} return TimeSliderChoropleth(gpolys.to_json(), styledict=styledict)
def make_map(gdf, geo, features): """ Returns a HTML file with time interactive choropleth plot """ m = folium.Map([22, 82], tiles="Stamen Terrain", zoom_start=5) g = TimeSliderChoropleth(geo, styledict=features).add_to(m) colormap.add_to(m) style = {"fillColor": "#00000000", "color": "#00000000"} #### adding tooltip ##### """folium.GeoJson(geo, tooltip = folium.features.GeoJsonTooltip( fields=['DISTRICT']),style_function=lambda x: style, ).add_to(m)""" for index, row in gdf.iterrows(): gs = folium.GeoJson(row["geometry"], style_function=lambda x: style) label = create_popup(index, row["DISTRICT"]) folium.Popup(label, max_width=2560).add_to(gs) gs.add_to(m) if index % 20 == 0: print("Done for Districts ", index, " out of 640") m.save("TimeSliderChoropleth.html") print("Map created") return m
def choropleth_map(type_of_method, pop_choice): canada_shape = json_sources() viz_dict, cmap = data_for_viz(type_of_method, pop_choice=pop_choice) m = folium.Map(location=[48, -102], zoom_start=4) TimeSliderChoropleth(data=canada_shape.to_json(), styledict=viz_dict, name='Waste by province').add_to(m) folium.LayerControl().add_to(m) m.add_child(cmap) m.save('{} and {} to population ratio.html'.format(type_of_method, pop_choice)) return m
def generate_map(joined_sum, states_geo): max_colour = max(joined_sum['deaths']) min_colour = min(joined_sum['deaths']) cmap = cm.linear.YlOrRd_09.scale(min_colour, max_colour) cmap = cmap.to_step(index=[0, 2000, 6000, 10000, 20000, 30000]) joined_sum['colour'] = joined_sum['deaths'].map(cmap) ## Construct the styling dictionary to apply styles to each county for each data point state_list = joined_sum['state'].unique().tolist() state_ndx = range(len(state_list)) style_dict = {} for i in state_ndx: state = state_list[i] result = joined_sum[joined_sum['state'] == state] inner_dict = {} for _, r in result.iterrows(): inner_dict[r['date_sec']] = {'color': r['colour'], 'opacity': 0.7} style_dict[str(i)] = inner_dict ## Then create a geo-dataframe containing the features for each county. states_geom = states_geo[['geometry']] states_gdf = gpd.GeoDataFrame(states_geom) states_gdf = states_gdf.reset_index() ## Now create the final Folium map objects. from folium.plugins import TimeSliderChoropleth slider_map = folium.Map(location=[37, -96], min_zoom= 4, max_bounds=True, max_zoom=18, zoom_start=4, height='75%', tiles='cartodbpositron') slider = TimeSliderChoropleth( data=states_gdf.to_json(), styledict=style_dict, overlay=True ).add_to(slider_map) slider = cmap.add_to(slider_map) cmap.caption = "Number of confirmed COVID19 Deaths" slider_map.save(outfile='usa_choropleth_chart.html') return True
def plot_traffic_data_over_time(): '''Function that plots all Seattle traffic data by zipcode over the time period 2007-2018.''' print('Function takes a moment to run. Please wait.') # Aggregate all traffic data by year agg_year_data = get_agg_year() # Download zip bounds zip_bounds = get_zipcode_bounds() # Set aggregated year data to zip bound coordinate system agg_year_data.crs = zip_bounds.crs # Spatial join the aggregated traffic data with the # zip codes to get zipcode for each street points city_by_zip = gpd.sjoin(zip_bounds, agg_year_data, op='intersects') city_by_zip.reset_index(inplace=True) # Select only the necessary columns city_by_zip = city_by_zip[['GEOBASID', 'ZIPCODE', 'YEAR', 'AAWDT', 'geometry']] # Dissolve data by zipcode and year to # aggregate data within geographic area # and keep year info. zips_years = city_by_zip.dissolve(by=['YEAR', 'ZIPCODE'], aggfunc=sum) zips_years.reset_index(inplace=True) # TimeSliderChoropleth example found here: # https://www.analyticsvidhya.com/blog/2020/06/guide-geospatial-analysis-folium-python/ # noqa: E501 from folium.plugins import TimeSliderChoropleth # Convert time data from just year to year-month-day format zips_years['ModifiedDateTime'] = pd.Series( pd.to_numeric( zips_years['YEAR'], errors='coerce' ), dtype='int64') zips_years.ModifiedDateTime.fillna(0) zips_years['ModifiedDateTime'] = zips_years['ModifiedDateTime']*1e4+101 zips_years['ModifiedDateTime'] = pd.to_datetime( zips_years['ModifiedDateTime'].astype('int64').astype('str') ) # Convert traffic data from strings to numbers zips_years['AAWDT'] = zips_years['AAWDT'].astype(int) # Create bins for choropleth scale bins = np.linspace(min(zips_years['AAWDT']), max(zips_years['AAWDT']), 11) # Create color column for AAWDT data based on RdYlBu_r hex keys color_list = ['#313695', '4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', 'a50026'] zips_years['color'] = pd.cut( zips_years['AAWDT'], bins, labels=[color_list], include_lowest=True ) # Select relevant columns zips_years = zips_years[['ModifiedDateTime', 'ZIPCODE', 'AAWDT', 'color', 'geometry']] # Convert time to ms format needed for TimeSliderChoropleth zips_years['ModifiedDateTime'] = ( zips_years['ModifiedDateTime'].astype(int) // 10**9 ).astype('U10') # Make zipcodes a str for the map zips_years['ZIPCODE'] = zips_years['ZIPCODE'].astype(str) # Create a style dictionary for the map traffic_dict = {} for i in zips_years['ZIPCODE'].unique(): traffic_dict[i] = {} for j in zips_years[ zips_years['ZIPCODE'] == i ].set_index(['ZIPCODE']).values: traffic_dict[i][j[0]] = {'color': j[1], 'opacity': 0.8} m2 = folium.Map([47.65, -122.3], tiles='cartodbpositron', zoom_start=10) TimeSliderChoropleth( zips_years.set_index('ZIPCODE').to_json(), styledict=traffic_dict ).add_to(m2) return m2
dt_index_epochs = datetime_index.astype(int) data_frame['dt_index'] = dt_index_epochs.astype('U10') viz_frame = pd.merge(data_frame, canada_shape, on="PREABBR") # Color scale for Choropleth: Amount of waste and color determination max_color = max(data_frame['Quantity_converted']) min_color = min(data_frame['Quantity_converted']) cmap = cm.linear.YlOrRd_09.scale(min_color, max_color) cmap.caption = "Amount of waste disposed by provinces" viz_frame['color'] = viz_frame['Quantity_converted'].map(cmap) # Styledict for TimesliderChoropleth: Choropleth dictionary province_list = canada_shape['PREABBR'].unique().tolist() viz_dict = {} for i in canada_shape.index: province = canada_shape['PREABBR'][i] result = viz_frame[viz_frame['PREABBR'] == province] inner_dict = {} for index, r in result.iterrows(): inner_dict[r['dt_index']] = {'color': r['color'], 'opacity': 0.7} viz_dict[i] = inner_dict # Choropleth test: Html visualization output m = folium.Map(location=[48, -102], zoom_start=4) TimeSliderChoropleth(data=canada_shape.to_json(), styledict=viz_dict, name='Waste by province').add_to(m) folium.LayerControl().add_to(m) m.add_child(cmap) m.save('choropleth_test_1.html')
def generate_map(self, total_cases, continent="World", optimize=True, outfile='map.html'): """ :param total_cases: str :param continent: str :param optimize: bool: True False to make map with all tooltips WARNING! can cause MemoryError! :param outfile: str name of the outer file """ if continent not in [ 'Europe', 'Asia and Pacific', 'Africa', 'North America', "South America" ]: continent = 'World' # continent and center of the continent with zoom continent_locations = { 'World': [45, 45, 1], 'Europe': [50, 5, 3], 'North America': [48, -102, 3], 'South America': [-26, -60, 3], 'Africa': [9, 35, 3], 'Asia and Pacific': [0, 100, 2.5] } countries_df, style_dict = self.process_joined_df(total_cases, continent=continent) continent_data = continent_locations[continent] # drop cols for faster processing countries_gdf = gpd.GeoDataFrame(countries_df[['geometry']]) countries_gdf = countries_gdf.drop_duplicates().reset_index() slider_map = folium.Map(min_zoom=2, zoom_start=continent_data[2], location=continent_data[0:2], max_bounds=True, tiles='cartodbpositron') TimeSliderChoropleth( data=countries_gdf.to_json(), styledict=style_dict, ).add_to(slider_map) # again drop cols but leave header and tooltip countries_gdf = gpd.GeoDataFrame( countries_df[['geometry', 'header', 'tooltip']]) # if optimized - leave only last day data if optimize: countries_gdf = countries_gdf.drop_duplicates(subset=['geometry'], keep="last") # add tooltip layer to map folium.GeoJson( data=countries_gdf.to_json(), style_function=lambda x: { 'color': 'black', 'weight': 1 }, tooltip=folium.features.GeoJsonTooltip( fields=['header', 'tooltip'], aliases=['', '']), ).add_to(slider_map) location = f'corona_full/templates/maps/{outfile}' slider_map.save(outfile=location) # set current time slider val to max query = '"value", 0' timestamplast = 'var current_timestamp = timestamps[timestamps.length - 1];' current_timestamp = 'var current_timestamp = timestamps[0];' with open(location, 'r') as fr: data = fr.read().replace(query, '"value", timestamps.length - 1') data = data.replace(current_timestamp, timestamplast) with open(location, 'w') as fw: fw.write(data)
recordindex = 0 for pref in df_7d.index: d = pd.DataFrame( { 'color': df_7d.loc[pref, :].apply(linear).tolist(), 'opacity': np.full(nn, 0.7), }, index=dayslist) data[recordindex] = d recordindex += 1 styledict = {pref: v.to_dict(orient='index') for pref, v in data.items()} m = folium.Map(location=[43.067392, 141.351137], zoom_start=5, tiles='cartodbpositron') g = TimeSliderChoropleth(src, styledict=styledict, overlay=True).add_to(m) folium.Marker( location=[43.804788, 143.831717], popup= "北見綜合卸センター Event 2/13-15 FirstOutbreak 2/16 FirstReport 2/22 Cluster 2/27" ).add_to(m) #folium.Marker(location = [43.054273, 141.353794],popup = "SingSingSing", ).add_to(m) folium.Marker( location=[43.060967, 141.348851], popup="さっぽろ雪まつり Event2/1-12 FirstOutbreak 2/8 FirstReport 2/19").add_to(m) #folium.Polygon(locations=[[43.0,141.5],[43.0,141.25],[43.1666,141.25],[43.1666,141.5]],color = 'black',weight=3).add_to(m) #folium.Polygon(locations=[[43.9166,143.625],[43.6666,143.625],[43.6666,144.0],[43.9166,144.0]],color = 'black',weight=3).add_to(m) m.add_child(linear) m.save('Prospective_3D.html')
def graph(data_frame, n_periods, freq, name, start_day): """ input : data_frame :: pandas data_frame of data, n_periods :: int, freq :: string, name :: string, start_day :: string data_frame must be in followign format aggreagted values for borough(0:4) for every row, each row is seperated by freq. n_periods : number of rows freq : Time gap between each period in format {'%nH','%nM','%nD'} where %n can be integer value specifying scalar multiple of hour/day/month name : format of %name.html that will save result map start_time : format of "YYYY-MM-DD" to mark start date of period saves the map out : None """ m = folium.Map(location=[40.718, -73.98], zoom_start=10) folium.TileLayer('cartodbpositron').add_to(m) datetime_index = pd.date_range(start_day, periods=n_periods, freq=freq) dt_index = datetime_index.astype(int).astype('U10') styledata = {} """ borough title : 0 is Staten Island 1 is Queens 2 is Brooklyn 3 is manhatan 4 is Bronx """ for borough in range(0, 4): df = pd.DataFrame( { 'color': data_frame.iloc[:, borough].values, 'opacity': data_frame.iloc[:, borough].values }, index=dt_index) df.sort_index() styledata[borough] = df max_color, min_color, max_opacity, min_opacity = 0, 0, 0, 0 for borough, data in styledata.items(): max_color = max(max_color, data['color'].max()) min_color = min(max_color, data['color'].min()) max_opacity = max(max_color, data['opacity'].max()) max_opacity = min(max_color, data['opacity'].max()) cmap = linear.PuRd_09.scale(min_color, max_color) #convert color value to hexcolor #and normalize the opacity for country, data in styledata.items(): data['color'] = data['color'].apply(cmap) data['opacity'] = data['opacity'] styledict = { str(borough): data.to_dict(orient='index') for borough, data in styledata.items() } #load the geojson file that we have nyc_zone = os.path.join('./', 'newyorkborough.json') nyc_json = json.load(open(nyc_zone)) #create timesliderchoropleth with geojson file & style as arguments and add it to the map g = TimeSliderChoropleth(nyc_json, styledict=styledict).add_to(m) #save the map title_statement = "<h1>" + name + "</h1>" m.get_root().html.add_child(folium.Element(title_statement)) colormap = linear.OrRd_08.scale(min_color, max_color) colormap.caption = 'Ride count in New York boroughs' colormap.add_to(m) m.save(name + ".html")
for street in active_streets: street = street.replace('ß', 'SS') idx_date = all_dates.index(str(date_ns)) for i, poss_date in enumerate(list(styledict[street].keys())): if i==idx_date: styledict[street][str(date_ns)]['color']='#8B0000' styledict[street][str(date_ns)]['opacity']=0.7 # elif not abs(i-idx_date)<5: # del styledict[street][poss_date] # folium.GeoJson(data=data, style_function=lambda x:{'color':'#8B0000'}).add_to(m) g = TimeSliderChoropleth( name='Sperrmüllkarte Karlsruhe 2022', data=data, styledict=styledict, ).add_to(m) # folium.Popup({'name'}).add_to(g) # g m.save(html_file) with open(html_file, 'r') as f: html = f.read() html = html.replace('<div class="folium-map"', '''<b>Sperrmüllkarte Karlsruhe 2022</b><br> Verschiebe den Regler auf das gewünschte Datum. Sperrmüllregion wird rot eingezeichnet
result = final_df[final_df['Town'] == town_name] inner_dict = {} for row_index, row in result.iterrows(): inner_dict[row['date_sec']] = {'color': row['colour'], 'opacity': 0.7} style_dict[str(i)] = inner_dict print(style_dict) ##data towngeometry_df = final_df[['geometry']] towngeometry_gdf = gpd.GeoDataFrame(towngeometry_df) towngeometry_gdf = towngeometry_gdf.drop_duplicates().reset_index() towngeometry_gdf slider_map = folium.Map(location=[25.2207, 67.1411], min_zoom=2,zoom_start=8.5, max_bounds=True,tiles='cartodbpositron') TimeSliderChoropleth(data=towngeometry_gdf.to_json(),styledict=style_dict,).add_to(slider_map) colour_bar.add_to(slider_map) colour_bar.caption = "Number of Crime Cases" slider_map #Reading Map file for Karachi Districts map_df2 = gpd.read_file('../input/aiproject-database/pakistan-districts.json') map_df2.head() #Reading Data file for Karachi district Crime Rate data_df2 = pd.read_csv('../input/aiproject-database/districtwise_data.csv') data_df2.head() #Merging both files map_df2.rename(columns={'NAME_3': 'District'},inplace=True) merged_df2= map_df2.merge(data_df2, on = 'District', how = 'left')
zilla_list = joined_df['Zilla'].unique().tolist() zilla_idx = range(len(zilla_list)) style_dict = {} for i in zilla_idx: zilla = zilla_list[i] result = joined_df[joined_df['Zilla'] == zilla] inner_dict = {} for _, r in result.iterrows(): inner_dict[r['date_sec']] = {'color': r['colour'], 'opacity': 0.8} style_dict[str(i)] = inner_dict #Then we need to make a dataframe containing the features for each country: zilla_df = joined_df[['geometry']] zilla_gdf = gpd.GeoDataFrame(zilla_df) zilla_gdf = zilla_gdf.drop_duplicates().reset_index() # Finally, we create our map and add a colourba slider_map = folium.Map(location=(23.6850, 90.3563), zoom_start=6.5, tiles='cartodbpositron') _ = TimeSliderChoropleth( data=zilla_gdf.to_json(), styledict=style_dict, ).add_to(slider_map) _ = cmap.add_to(slider_map) cmap.caption = "Log of number of confirmed cases" slider_map.save(outfile='Time_mapping.html')
def create_folium_choropleth(geojson, data, map_settings): """Create a folium choropleth map. Parameters ---------- geojson : dict A geojson layer to add to the map. data : dict The raw data to use for coloring. map_settings : dict A dict containing settings for initializing the map. Returns ------- the_map : object like folium.folium.Map The map created here. """ the_map = folium.Map( location=map_settings.get('center', [63.447, 10.422]), tiles='cartodbpositron', zoom_start=map_settings.get('zoom', 9), ) use_logscale = map_settings.get('logscale', True) countries = list(sorted(data['country'].unique())) column = map_settings.get('column', 'sum_cases') column_name = map_settings.get('column_name', 'Cases') print('Log:', use_logscale) print('Column:', column) min_value = map_settings.get('min_value', None) max_value = map_settings.get('max_value', None) mini, maxi = get_min_max(data, countries, column, log=use_logscale) if min_value is None: min_value = mini if max_value is None: max_value = maxi # Create color map: color_map_name = map_settings.get('color_map', 'Reds_03') color_map = cm.LinearColormap( COLOR_MAPS[color_map_name], vmin=min_value, vmax=max_value, ) # Create styles for selected countries: styles = create_style(data, geojson, column, countries, color_map, log=use_logscale, threshold=map_settings.get('threshold', None)) dates = (data['date'].unique().astype(int) // 10**9).astype('U10') # Restructure style dict to contain dates: style_dict = {} for key, val in styles.items(): style_dict[key] = {} for datei, vali in zip(dates, val): style_dict[key][datei] = vali slider = TimeSliderChoropleth( geojson, styledict=style_dict, ).add_to(the_map) if use_logscale: color_map.caption = '{} (log scale)'.format(column_name) else: color_map.caption = column_name the_map.add_child(color_map) return the_map
cmap = linear.PuRd_09.scale(min_color, max_color) def norm(x): return (x - x.min()) / (x.max() - x.min()) for code, data in styledata.items(): data['color'] = data['color'].apply(cmap) data['opacity'] = norm(data['opacity']) styledict = { str(code): data.to_dict(orient='index') for code, data in styledata.items() } # Add the color for the chloropleth: TimeSliderChoropleth( data=worldmap, styledict=styledict, name='monkey booze', # data=measles_disease_datam, # columns=['ISO3', '2012'], # key_on='feature.id', ).add_to(m) folium.LayerControl().add_to(m) # Save to html m.save('slider.html')
def create_gdp_viz(): ''' Load and pre-process the geojson file ''' geojson_path = os.path.normpath( os.path.join(script_dir_path, '..', 'data', 'borders_geo.json')) world_geojson = gpd.read_file(geojson_path) world_geojson.drop(columns=['ISO_A2', 'ADMIN'], inplace=True) world_geojson.drop(world_geojson[world_geojson['ISO_A3'] == '-99'].index, inplace=True) country_list = world_geojson['ISO_A3'].tolist() ''' Load and pre-process the GDP data ''' # Load the GDP data df_GDP_path = os.path.normpath( os.path.join(script_dir_path, '..', 'data', 'GDP_per_capita_world_data.csv')) df_GDP = pd.read_csv(df_GDP_path, index_col='Country Code', skiprows=4) # Drop unnecessary data df_GDP.drop(labels='2020', axis=1, inplace=True) csv_country_list = df_GDP.index.tolist() country_list = list(set(country_list).intersection(csv_country_list)) df_GDP.drop(df_GDP[~df_GDP.index.isin(country_list)].index, inplace=True) world_geojson.drop( world_geojson[~world_geojson['ISO_A3'].isin(country_list)].index, inplace=True) country_list.sort() # Create an enumerated country dict for id mapping country_dict = {k: v for v, k in enumerate(country_list)} world_geojson['country_id'] = world_geojson['ISO_A3'].map(country_dict) # Count min and max GDP values min_GDP_val, max_GDP_val = df_GDP[df_GDP.columns[4:]].min().min(), df_GDP[ df_GDP.columns[4:]].max().max() # Create a color list color_list = [ '#808080', '#A50026', '#D73027', '#F46D43', '#FDAE61', '#FEE08B', '#FFFFBF', '#D9EF8B', '#A6D96A', '#66BD63', '#1A9850', '#006837' ] # Create a list of geometrically spaced numbers over a min-max interval bins = np.geomspace(min_GDP_val, max_GDP_val, 12) # Replace NaNs (records with no data available) with '-1' df_GDP.fillna(-1, inplace=True) # Add NaN category to the bins bins = np.insert(bins, 0, -1.) bins = bins.tolist() # Append 'color_[year]' columns to the GDP DataFrame year = 1960 while year <= 2019: pasted_col_id = df_GDP.columns.get_loc(str(year)) + 1 col_value = pd.cut(df_GDP[str(year)], bins, include_lowest=True, labels=[ '#808080', '#A50026', '#D73027', '#F46D43', '#FDAE61', '#FEE08B', '#FFFFBF', '#D9EF8B', '#A6D96A', '#66BD63', '#1A9850', '#006837' ]) df_GDP.insert(loc=pasted_col_id, column='color_' + str(year), value=col_value) year += 1 print(df_GDP) ''' Create appropriately formatted dictionary that the TimeSliderChoropleth will receive as an input ''' gdp_dict = {} for country_code in df_GDP.index.tolist(): country_id = str(country_dict[country_code]) gdp_dict[country_id] = {} year = 1960 while year <= 2019: dt_obj = datetime(year=year, month=12, day=31) year_in_ms = str(time.mktime(dt_obj.timetuple())) color_hex = df_GDP.at[country_code, 'color_' + str(year)] gdp_dict[country_id][year_in_ms] = { 'color': color_hex, 'opacity': 0.7 } year += 1 ''' Initialize the map ''' map_GDP = folium.Map(location=[0, 0], zoom_start=4, max_bounds=True, min_zoom=3) ''' Create the map content and add it to the map object ''' # Create the choropleth choropleth = TimeSliderChoropleth( world_geojson.set_index('country_id').to_json(), styledict=gdp_dict) choropleth.add_to(map_GDP) # Create the map legend legend_labels_dict = {} i = 0 for color in color_list: if i == 0: legend_labels_dict[color_list[i]] = 'No data' elif i == len(color_list) - 1: legend_labels_dict[color_list[i]] = '> ' + str(round(bins[i], 2)) + '$' break else: legend_labels_dict[color] = str(round( bins[i], 2)) + '$' + ' - ' + str(round(bins[i + 1], 2)) + '$' i += 1 template = utils.create_legend(caption='GDP per capita in USD', legend_labels=legend_labels_dict) macro = MacroElement() macro._template = Template(template) map_GDP.get_root().add_child(macro) ''' Save completed map viz to an appropriate folder ''' map_GDP.save( os.path.join(script_dir_path, '..', 'webapp', 'templates', 'GDP_viz.html')) print('Successfully created the GDP viz!')
return (x - x.min()) / (x.max() - x.min()) for country, data in styledata.items(): data['color'] = data['color'].apply(cmap) data['opacity'] = norm(data['opacity']) styledict = { str(country): data.to_dict(orient='index') for country, data in styledata.items() } from folium.plugins import TimeSliderChoropleth m = folium.Map([0, 0], tiles='Stamen Toner', zoom_start=2) g = TimeSliderChoropleth( gdf.to_json(), styledict=styledict, ).add_to(m) #m.save(os.path.join('results', 'TimeSliderChoropleth.html')) #m import os import webbrowser filepath = '/Users/abbassalsharif/Documents/GitHub/DSO545/02_Sessions/Week_10/map.html' m.save(filepath) webbrowser.open('file://' + filepath)