def test_simple_step(): step = cm.StepColormap(['green', 'yellow', 'red'], vmin=3., vmax=10., index=[3, 4, 8, 10], caption='step') step = cm.StepColormap(['r', 'y', 'g', 'c', 'b', 'm']) step._repr_html_()
def update_homo_area(self): # On change les donnes de Gab if self.distance_choice in ["compas","compas_asym"]: variable = "WME" else: variable = "W1" (code,hexc,_) = geo_gv.get_cmap_info(variable) cmap = cm.StepColormap(hexc.values,index=np.asarray(code).astype(float),vmin=code[0],vmax=code[-1]+1) chor_layer2 = ipyl.Choropleth(geo_data=self.region_geo2, choro_data=self.homo_zone, name="zonage sur homogeneous temps sensible criterion ("+self.distance_choice+")", value_min = float(code[0]), value_max = float(code[-1]+1), colormap = cmap, border_color="red", style={'fillOpacity': 0.8, 'dashArray': '5, 5',"opacity":0.5}, hover_style={"opacity":1,"color":"black","weight":4}) chor_layer2.value_min = float(code[0]) chor_layer2.value_max = code[-1]*1.0 if hasattr(self,"chor_layer2"): if self.chor_layer2 in self.m.layers: #print("et par la") self.m.substitute_layer(self.chor_layer2,chor_layer2) else: #print('et ici') self.m.add_layer(chor_layer2) else: #print('et ou la') self.m.add_layer(chor_layer2) self.chor_layer2 = chor_layer2 self.chor_layer2.on_hover(self.update_chor_html2)
def test_step_to_linear(): step = cm.StepColormap(['green', 'yellow', 'red'], vmin=3., vmax=10., index=[3, 4, 8, 10], caption='step') step.to_linear()
def colormap(m, index, caption): """ Def a color map, need the map m, an array of colors with a matching index and caption for the name. """ CB = cm.StepColormap(colors, vmin=0, vmax=50, index=index, caption=caption) m.add_child(CB)
def add_colorbar(self): """add a colorbar at the top right corner of the map""" vmin, vmax = self.df["price"].quantile(0.005), self.df["price"].max() # set vmin to price.min() will screw the colorbar scale colormap = cm.StepColormap(self.color_codes, index=self.index, vmin=vmin, vmax=vmax) colormap.caption = "Monthly rent (€)" self.map.add_child(colormap)
def test_max_labels_step(max_labels, expected): colorbar = cm.StepColormap(['red', 'blue'] * 5, vmin=0, vmax=10, max_labels=max_labels) try: colorbar.render() except AssertionError: # rendering outside parent Figure raises error pass assert colorbar.tick_labels == expected
def colormap(m, index, caption): """ Def a color map, need the map m, an array of colors with a matching index and caption for the name. """ #CB= cm.StepColormap(colors, vmin=0,vmax=10,index=index, caption=caption ) print("in colormap colorbar_values=", colorbar_values[0], colorbar_max_value) print(colorbar_values) CB = cm.StepColormap(colors, vmin=colorbar_values[0], vmax=colorbar_max_value, index=colorbar_values[:], caption=caption) m.add_child(CB)
def plot_isochrone(source, source_coords, stations_data, cutoff, threshold, G): # Plot the isochrone map color_bar = cm.StepColormap(['blue', 'red', 'yellow', 'green'], index=[0, 0.25, 0.50, 0.75, 1]) color_bar.caption = 'Trip Uncertainty' m = folium.Map(source_coords, zoom_start=13, tiles='Stamen toner') m.add_child(color_bar) popup_data = {} for station_data in stations_data: station_name = station_data[0] quality = station_data[2] arrival_time = station_data[3] lat, long = G.node[station_name]['lat'], G.node[station_name]['lon'] popup_data['station_name'] = station_name popup_data['arrival_time'] = arrival_time add_circle(m, (lat, long), quality, time_diff(cutoff, arrival_time), popup_data, color_bar) return m
def FoliumMapAB(mapobj,dat,colorFac='IF_Adj',ColBins=7): ''' mapobj = folium map object dat = Geopandas dataframe used for plotting ColBins = # of color bins needed ''' #Get dat into GeoPandas DataFrame dat = gpd.GeoDataFrame(dat,crs={'init': 'epsg:4326'}) datJson = dat.to_json() # ############################### #datJson has "id" node which is the index for the "dat". BUT it is string so convert your # index to strings. #Create a key value pair for color coding lines: dat_dict = dat.set_index(dat.index.astype('str'))[colorFac] Min1 =dat[colorFac].min() Max1 =dat[colorFac].max() ########################################################## #https://github.com/python-visualization/folium/blob/master/examples/Colormaps.ipynb #Color Code Lines: #sns.palplot(sns.color_palette("YlOrRd", ColBins-1)) GrYlRe_Pal = ["green"] +sns.color_palette("YlOrRd", ColBins-1) l1 = np.linspace(7,Max1,ColBins).astype('int').tolist() l1 = [Min1]+l1 colormap = cm.StepColormap( GrYlRe_Pal, vmin=Min1, vmax=Max1, index=l1, caption='Adjusted Incident Factor for I-40 and I-95') #Add lines on map folium.GeoJson( datJson, name= 'Adjusted IF Heatmap', style_function=lambda feature: { 'fillColor': colormap(dat_dict[feature['id']]), 'color': colormap(dat_dict[feature['id']]), 'weight': 4, 'dashArray': '5, 5' }).add_to(mapobj) #Add Legend colormap.add_to(mapobj) return mapobj
def plot_avg_price_on_map(df): df['lat'] = [round(x, 2) for x in df['lat']] df['long'] = [round(x, 2) for x in df['long']] df = df.groupby(by=['lat', 'long'])['price'].mean().reset_index() print(len(df)) map_template = folium.Map(tiles='cartodbpositron', location=[47, -122], zoom_start=6) color = list(Spectral9) colormap = cm.StepColormap(color, vmin=df["price"].min(), vmax=df["price"].max()) diff = df["price"].max() - df["price"].min() range_diff = int(diff / len(color)) + 1 for row_number, row in df.iterrows(): n_color = int(row['price'] / range_diff) if n_color > 8: n_color = 8 n_size = row['price'] / 1000000 if n_size < 2: n_size = 1 folium.CircleMarker([row['lat'], row['long']], radius=n_size, popup="average price: " + str(round(row['price'])), color=color[n_color], fill_color=color[n_color]).add_to(map_template) map_template.add_child(colormap) f = folium.Figure() string = "Average home price" f.html.add_child( folium.Element("<font face='helvetica'><font size='5'><b><p1>" + string + "</b></font></p1>")) f.add_child(map_template) map_template.save('average_home_price_map.html')
def update_HSS_area(self): # On change les donnees de Mary if hasattr(self,"dfres"): # On choisit (par defaut) le code WME a afficher pour Mary if self.distance_choice in ["compas","compas_asym"]: variable = "WME" else: variable = "W1" (code,hexc,_) = geo_gv.get_cmap_info(variable) cmap = cm.StepColormap(hexc.values,index=np.asarray(code).astype(float),vmin=code[0],vmax=code[-1]+1) chor_layer = ipyl.Choropleth( geo_data=self.region_geo, choro_data=self.mary_zone.to_dict(), name="zonage sur temps sensible (WME)", value_min = float(code[0]), value_max = float(code[-1]+1), colormap = cmap, border_color='blue', style={'fillOpacity': 0.8, 'dashArray': '5, 5'}, hover_style={"opacity":1,"color":"black","weight":4}) chor_layer.value_min = float(code[0]) chor_layer.value_max = code[-1]*1.0 if hasattr(self,"chor_layer"): if self.chor_layer in self.m.layers: #print("on passe la") self.m.substitute_layer(self.chor_layer,chor_layer) else: #print("ici") self.m.add_layer(chor_layer) else: #print('ou la') self.m.add_layer(chor_layer) self.chor_layer = chor_layer self.chor_layer.on_hover(self.update_chor_html) else: if hasattr(self,"chor_layer") and self.chor_layer in self.m.layers: self.m.remove_layer(self.chor_layer)
del outDataRaster ## delete the data (not the actual geotiff) gdal.Warp("projected_output.tif","pca_kmeans_output.tif",dstSRS='EPSG:4326') """# Visualize classified image on map using Folium""" with rio.open("projected_output.tif") as src: dataset = src.read() meta = src.meta ymin = src.bounds[1] xmin = src.bounds[0] ymax = src.bounds[3] xmax = src.bounds[2] dataset = dataset[0,:,] dataset[np.isnan(dataset)] = 0 ### Handling nan values dataimage=dataset step = cm.StepColormap([(255,255,255,1), (56,168,0), (0, 38, 115), (38, 115, 0), (255,211,127), (230, 0, 169),(0, 0, 0)], vmin=0, vmax=6, index=[0,0.1, 1, 2, 3,4,5,6], caption="step") step.caption = '1-Low Vegetation,2-Waterbodies, 3-Roads, 4-Land surface, 5-Urban,6-Dense Vegetation ' token = "pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw" # your mapbox token tileurl = 'https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}@2x.png?access_token=' + str(token) m = folium.Map([(ymax+ymin)/2,(xmax+xmin)/2], zoom_start=10) folium.TileLayer(tiles=tileurl,attr='Mapbox',name="Mapbox Satellite Imagery").add_to(m) folium.raster_layers.ImageOverlay(name="Classified Hyperspectral Image",image=dataimage, bounds=[[ymin, xmin], [ymax, xmax]], colormap=lambda x: step.rgba_bytes_tuple(x) , opacity = 1,).add_to(m) m.add_child(step) folium.LayerControl().add_to(m) m.save("map.html") m
"#b15928", "#FFFFFF", "#000000", ] # Trim colour list to number of clusters if k_opt <= len(color_list): color_list = color_list[:k_opt] else: print( "Warn: Number of clusters ({}) is larger than colours available ({})".format( k_opt, len(color_list) ) ) # Warning won't trigger so long kmax <= color_list color_step = cmp.StepColormap(color_list, vmin=1, vmax=k_opt, caption="Clusters",) cluster_dict = cluster_geodf.set_index("Subzone")["cluster"] # %% # Plot Subzones clusters on Map m5 = folium.Map(location=[1.3521, 103.8198], tiles="cartodbpositron", zoom_start=11) # Colouring Subzones based on Clusters cluster_gj = folium.GeoJson( cluster_geodf, style_function=lambda feature: { "fillColor": color_step(cluster_dict[feature["properties"]["Subzone"]]), "color": color_step(cluster_dict[feature["properties"]["Subzone"]]), "fillOpacity": 0.5, "weight": 1,
# for d in (range(100)): #測試資料筆數 # for m in (range(50)): #找是在哪列 # if lon_min[list1[m]-1]<lon[d] and lon[d]<lon_max[list2[m]-1] and lat_min[list1[m]-1]<lat[d] and lat[d]<lat_max[list2[m]-1]: # for n in range(list1[m],list2[m]+1): #找是在該列的哪個 # if lon_min[n-1]<lon[d] and lon[d]<lon_max[n-1] and lat_min[n-1]<lat[d] and lat[d]<lat_max[n-1]: # ans_Id[d]=Id[n]-1 taichungmap_1x1 = taichungmap_1x1.merge(all_point_data_mix, on='Id') taichungmap_1x1['PM2.5']=taichungmap_1x1['PM2.5'].round() taichung_district = taichung_district.merge(weather, on='區名') #taichung_district #================================================================================================== #folium variable = 'PM2.5' colorList = ['#98fb98','#00ff00','#32cd32','#ffff00','#ffd700','#ffa500','#ff6347','#ff0000','#ba55d3'] map_color = cm.StepColormap(colorList,index=[0,10,20,30,40,50,60,70,80],vmin=0,vmax=100,caption = 'PM2.5') fmap=folium.Map(location=[24.2,120.9], zoom_start=10.5) #fmap.choropleth( # geo_data=taichungmap_1x1, # name='pm2.5', # columns=['Id', 'PM2.5'], # key_on='feature.properties.Id', # data=all_point_data_mix, # #threshold_scale=[], # fill_color='BuGn', # legend_name='pm2.5', # line_opacity=0.5, # fill_opacity=0.8 # ) folium.GeoJson(
color='green' if row.thematic_area == 'Inspiring Civic Engagement & Service' else 'red' if row.thematic_area == "Improving Public Health" else 'blue', prefix='fa', icon='circle')).add_to(m) with open('countries.json') as geo_json_data: geo_json_data = json.load(geo_json_data) country_dict = df.set_index('state')['number'] country_dict = country_dict[~country_dict.index.duplicated(keep="first")] import branca.colormap as cm step = cm.StepColormap(['blue', 'red', 'green', 'purple', 'white'], vmin=1, vmax=6, index=[1, 1.9, 2.9, 3.9, 4.9, 5.9], caption='step') colormap = cm.StepColormap(['blue', 'red', 'green', 'purple', 'white'], vmin=1, vmax=6, index=[1, 1.9, 2.9, 3.9, 4.9, 5.9], caption='step') def style_function(feature): countried = country_dict.get(feature['id'], None) return { 'fillOpacity': 0.5, 'weight': 0.5,
def color_series(value_series, colors=[rainbow_shades[3], rainbow_shades[0]], index=None, max_value=None, min_value=None, method='linear', reversed_colors=False): """ :param value_series: the pd.Series that contain the values :param colors: list containing the colors used to build the color scale ['red', 'blue'] :param index: list containing the value corresponding to each color :param min_value: the values below min_values are given the same color : colors[0] :param max_value: value to use as the maximum when normalizing the series (to focus on low values). :param method: method used (linear or step) :return: color_series: pd.Series that contains the colors corresponding to the values :rtype: pd.Series example: :: import pandas as pd # common visualization library import matplotlib.pyplot as plt % matplotlib inline plt.rcParams['figure.figsize'] = [17,7] plt.rcParams['font.size'] = 20 # custom visualization library from syspy_utils import data_visualization, syscolors data = {'a': 1, 'b': 2, 'c': 3, 'd': 5, 'e': 7, 'f': 10} series = pd.Series(data) color_scale = ('#559BB4', '#D22328') color_series = data_visualization.color_series(series, colors=color_scale, min_value=2, max_value=6) dataframe = pd.DataFrame({'value': series, 'color': color_series, 'width': width_series}) series.plot(kind='bar', color=color_series) .. figure:: ./pictures/data_visualization_color_series.png :width: 25cm :align: center :alt: bar plot with color series :figclass: align-center bar plot with color series """ colors = list(reversed(colors)) if reversed_colors else colors max_value = max_value if max_value else np.max(list(value_series.values)) min_value = min_value if min_value else np.min(list(value_series.values)) if method == 'linear': if index == None: index = np.linspace(min_value, max_value, len(colors)) colormap = cm.LinearColormap(colors, index=index) else: if index == None: index = value_series.quantile(np.linspace(0, 1, len(colors))).values colormap = cm.StepColormap(colors, index=index) return value_series.apply( lambda x: colormap(max(min(x, max_value), min_value)))
df_loc = pd.DataFrame(addr_loc, columns=['latitude', 'longitude']) df = pd.concat([df, df_loc], axis=1) df_col = pd.DataFrame({ 'Status': [ "Bardzo dobry", "Dobry", "Umiarkowany", "Dostateczny", "Zły", "Bardzo zły" ], 'Color': ['blue', 'green', 'yellow', 'orange', 'red', 'black'] }) m = folium.Map(addr_loc[0], zoom_start=13, control_scale=True) legend = cm.StepColormap(df_col['Color'].values.tolist(), vmin=0, vmax=12) now = datetime.datetime.now() last_update = 'Ostatnia aktualizacja: {}'.format( now.strftime('%Y-%m-%d %H:%M:%S')) legend_html = ''' <div style="position: fixed; top: 50px; right: 150px; width: 300px; height: 90px; border:3px dark grey; z-index:9999; font-size:14px; "> {} <br> </div> '''.format(last_update) m.get_root().html.add_child(folium.Element(legend_html))
choro_map_data_covidxdep = dict( zip(xdepartamentos['unique_values'].tolist(), xdepartamentos['counts'].tolist())) # In[16]: colormap = cm.StepColormap( colors=[ '#FFA07A', '#F08080', '#CD5C5C', '#FF7F50', '#FF6347', '#DC143C', '#B22222', '#A52A2A' ], index=[ min(choro_map_data_covidxdep.values()), np.percentile(list(choro_map_data_covidxdep.values()), 12.5), np.percentile(list(choro_map_data_covidxdep.values()), 25), np.percentile(list(choro_map_data_covidxdep.values()), 37.5), np.median(list(choro_map_data_covidxdep.values())), np.percentile(list(choro_map_data_covidxdep.values()), 62.5), np.percentile(list(choro_map_data_covidxdep.values()), 75), np.percentile(list(choro_map_data_covidxdep.values()), 87.5), max(choro_map_data_covidxdep.values()) ], vmin=250, vmax=66000) # In[17]: layercoviddepa = ipyleaflet.Choropleth(geo_data=geo_json_data, choro_data=choro_map_data_covidxdep, colormap=colormap, border_color='black',
def create_covid_viz(): ''' Load and pre-process the geojson file ''' world_geojson = gpd.read_file(geojson_path) world_geojson.drop(columns=['ISO_A2'], inplace=True) ''' Load and pre-process the COVID-19 data ''' # Load the COVID-19 data df_covid = pd.read_csv( os.path.join(data_dir_path, 'covid_' + newest_dataset)) timestamp = df_covid['Last_Update'][0] # Replace some country names df_covid.replace(to_replace={'Country_Region': 'US'}, value='United States of America', inplace=True) df_covid.replace(to_replace={'Country_Region': 'Bahamas'}, value='The Bahamas', inplace=True) df_covid.replace(to_replace={'Country_Region': 'Congo (Brazzaville)'}, value='Republic of Congo', inplace=True) df_covid.replace(to_replace={'Country_Region': 'Congo (Kinshasa)'}, value='Democratic Republic of the Congo', inplace=True) df_covid.replace(to_replace={'Country_Region': 'Taiwan*'}, value='Taiwan', inplace=True) df_covid.replace(to_replace={'Country_Region': "Cote d'Ivoire"}, value='Ivory Coast', inplace=True) df_covid.replace(to_replace={'Country_Region': "Czechia"}, value='Czech Republic', inplace=True) world_geojson.replace(to_replace={'ADMIN': 'Macedonia'}, value='North Macedonia', inplace=True) # Change the name of 'ADMIN' column in the geojson DF to match the one in COVID DF world_geojson.rename(columns={'ADMIN': 'Country_Region'}, inplace=True) # Aggregate the data for countries that have regional information df_covid_agg = df_covid.groupby('Country_Region').agg({ 'Confirmed': 'sum', 'Deaths': 'sum', 'Recovered': 'sum', 'Active': 'sum', 'Incident_Rate': 'mean', 'Case_Fatality_Ratio': 'mean' }) world_geojson = world_geojson.sort_values('Country_Region').reset_index( drop=True) # Join the geojson with the DataFrame df_covid_joined = df_covid_agg.merge(world_geojson, how='right', on='Country_Region') # Count min and max values for specific columns min_dict, max_dict = {}, {} column_names = [ 'Confirmed', 'Deaths', 'Active', 'Incident_Rate', 'Case_Fatality_Ratio' ] for name in column_names: min_dict[name] = min(df_covid_joined[name]) max_dict[name] = max(df_covid_joined[name]) # Replace NaNs in the DataFrame with '-1' df_covid_joined.fillna(-1, inplace=True) # Add the data columns to geo json for future popup displaying world_geojson = world_geojson.assign( Confirmed=df_covid_joined['Confirmed'], Deaths=df_covid_joined['Deaths'], Active=df_covid_joined['Active'], Incident_Rate=df_covid_joined['Incident_Rate'], Case_Fatality_Ratio=df_covid_joined['Case_Fatality_Ratio']) print(world_geojson) # Set the correct index columns df_covid_joined.set_index('Country_Region', inplace=True) # Create a lists of evenly spaced attribute values over computed min-max intervals and assign corresponding colors to the DataFrame colormap_dict = {} bins = [] for name in column_names: # Work-around for geometric space not accepting zeros in the sequence tmp_min = min_dict[name] if min_dict[name] < 1: min_dict[name] = 1 inner_bins = np.geomspace(start=min_dict[name], stop=max_dict[name], num=10) min_dict[name] = tmp_min inner_bins = np.delete(inner_bins, 0) inner_bins = np.insert(inner_bins, 0, min_dict[name]) inner_bins = np.insert(inner_bins, 0, -1.) inner_bins = inner_bins.tolist() # Round the inner_bins values before appending to the bins list if name in ['Confirmed', 'Deaths', 'Active']: inner_bins = [int(round(bin, 0)) for bin in inner_bins] else: inner_bins = [round(bin, 2) for bin in inner_bins] bins.append(inner_bins) colormap_dict[name] = cm.StepColormap(colors=color_dict[name], index=inner_bins, vmin=min_dict[name], vmax=max_dict[name]) df_covid_joined[name + '_color'] = df_covid_joined[name].map( lambda x: colormap_dict[name].rgb_hex_str(x)) ''' Initialize the map ''' map_covid = folium.Map(location=[0, 0], zoom_start=4, max_bounds=True, tiles=None) base_map = folium.FeatureGroup(name='Basemap', overlay=True, control=False) folium.TileLayer(min_zoom=3, tiles='OpenStreetMap').add_to(base_map) base_map.add_to(map_covid) ''' Create the content of the map ''' # Create FeatureGroups to group the data feature_groups = [] for category, _ in color_dict.items(): group = folium.FeatureGroup(category, overlay=False) feature_groups.append(group) # Create the choropleths choropleth_confirmed = folium.GeoJson( data=world_geojson, zoom_on_click=False, name='Confirmed Cases', style_function=lambda x: { 'fillColor': df_covid_joined['Confirmed_color'][x['properties']['Country_Region' ]], 'fillOpacity': 0.7, 'color': 'black', 'weight': 0.5 }).add_to(feature_groups[0]) popup_confirmed = folium.GeoJsonPopup( fields=['Country_Region', 'Confirmed'], labels=False) popup_confirmed.add_to(choropleth_confirmed) choropleth_deaths = folium.GeoJson( data=world_geojson, name='Deaths', style_function=lambda x: { 'fillColor': df_covid_joined['Deaths_color'][x['properties']['Country_Region']], 'fillOpacity': 0.7, 'color': 'black', 'weight': 1 }).add_to(feature_groups[1]) popup_deaths = folium.GeoJsonPopup(fields=['Country_Region', 'Deaths'], labels=False) popup_deaths.add_to(choropleth_deaths) choropleth_active = folium.GeoJson( data=world_geojson, name='Active Cases', style_function=lambda x: { 'fillColor': df_covid_joined['Active_color'][x['properties']['Country_Region']], 'fillOpacity': 0.7, 'color': 'black', 'weight': 1 }).add_to(feature_groups[2]) popup_active = folium.GeoJsonPopup(fields=['Country_Region', 'Active'], labels=False) popup_active.add_to(choropleth_active) choropleth_incident_rate = folium.GeoJson( data=world_geojson, name='Incident Rate', style_function=lambda x: { 'fillColor': df_covid_joined['Incident_Rate_color'][x['properties'][ 'Country_Region']], 'fillOpacity': 0.7, 'color': 'black', 'weight': 1 }).add_to(feature_groups[3]) popup_incident_rate = folium.GeoJsonPopup( fields=['Country_Region', 'Incident_Rate'], labels=False) popup_incident_rate.add_to(choropleth_incident_rate) choropleth_case_fatality_ratio = folium.GeoJson( data=world_geojson, name='Case Fatality Ratio', style_function=lambda x: { 'fillColor': df_covid_joined['Case_Fatality_Ratio_color'][x['properties'][ 'Country_Region']], 'fillOpacity': 0.7, 'color': 'black', 'weight': 1 }).add_to(feature_groups[4]) popup_case_fatality_ratio = folium.GeoJsonPopup( fields=['Country_Region', 'Case_Fatality_Ratio'], labels=False) popup_case_fatality_ratio.add_to(choropleth_case_fatality_ratio) # Create the map legends templates legend_str_dict = {} for i, (k, v) in enumerate(color_dict.items()): legend_labels_dict = {} j = 0 for color in v: if j == 0: legend_labels_dict[color] = 'No data' elif j == len(v) - 1: legend_labels_dict[color] = '> ' + str(bins[i][j]) break else: legend_labels_dict[color] = str(bins[i][j]) + ' - ' + str( bins[i][j + 1]) j += 1 legend_str_dict[k] = legend_labels_dict template = utils.create_legend(caption='COVID-19 status as of: ' + str(timestamp) + ' UTC', legend_labels=legend_str_dict) macro = MacroElement() macro._template = Template(template) map_covid.get_root().add_child(macro) for feature_group in feature_groups: feature_group.add_to(map_covid) # Activate Layer Control folium.LayerControl(collapsed=True).add_to(map_covid) ''' Save completed map viz to an appropriate folder ''' map_covid.save( os.path.join(script_dir_path, '..', 'webapp', 'templates', 'COVID-19_viz.html')) print('Successfully created the COVID-19 viz!')