Ejemplo n.º 1
0
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_()
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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')
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
    "#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,
Ejemplo n.º 14
0
# 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(
Ejemplo n.º 15
0
            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,
Ejemplo n.º 16
0
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)))
Ejemplo n.º 17
0
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;
                            ">&nbsp; {} <br>
		     </div>
                '''.format(last_update)

m.get_root().html.add_child(folium.Element(legend_html))
Ejemplo n.º 18
0
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',
Ejemplo n.º 19
0
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!')