def draw_with_folium_by_device_and_year_dbscan_center_circle_style(): '''使用每人每个月的聚类中心坐标按照1-12月不同颜色去画圆 每年、每人生成一个html,html中12种颜色代表12个月 ''' try: #12种颜色分别是红、绿、蓝、黄、紫、粉、青、棕、橙、赤红、森林绿、板岩灰 twelve_months_color_list = ['#FF0000','#00FF00','#0000FF','#FFFF00','#800080','#FFC0CB','#00FFFF','#A52A2A','#FFA500','#DC143C','#228B22','#708090'] device_center_save_by_year_csv_dir = r'E:/test_opencv/员工打卡分析/device_center_save_by_year/' folium_device_center_save_by_year_circle_html_dir = r'E:/test_opencv/员工打卡分析/folium_device_center_save_by_year_circle_html/' if not os.path.exists(folium_device_center_save_by_year_circle_html_dir): os.makedirs(folium_device_center_save_by_year_circle_html_dir) for root, dirs, files in os.walk(device_center_save_by_year_csv_dir): longitude_center_list = [] latitude_center_list = [] for file in files: if os.path.isfile(os.path.join(root, file)): dbscan_center_coordinates_csv_name = os.path.join(root, file) '''处理dbscan聚类后中心点坐标''' df = pd.read_csv(dbscan_center_coordinates_csv_name, encoding='utf-8', low_memory=False) # 计算dataframe经纬度中心坐标 longitude_center = df['longitude'].mean() latitude_center = df['latitude'].mean() longitude_center_list.append(longitude_center) latitude_center_list.append(latitude_center) if longitude_center_list and latitude_center_list: longitude_cent = np.mean(longitude_center_list)#年度中心 latitude_cent = np.mean(latitude_center_list)#年度中心 else: continue m = folium.Map(location=[latitude_cent, longitude_cent], zoom_start=10, control_scale=True) macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro) for file in files: if os.path.isfile(os.path.join(root, file)): dbscan_center_coordinates_csv_name = os.path.join(root, file) '''处理dbscan聚类后中心点坐标''' df = pd.read_csv(dbscan_center_coordinates_csv_name, encoding='utf-8', low_memory=False) X = df device_id = X['device_id'].iloc[0] # 取组内第一个device_id用于存csv用 marketer_name = X['marketer_name'].iloc[0] # 取组内第一个marketer_name用于存csv用 clock_time_year_month = str(X['clock_time_year_month'].iloc[0]) # 取组内第一个clock_time_year_month用于存csv用 year_month = clock_time_year_month[0:4]+'年'+clock_time_year_month[4:6]+'月' month = int(clock_time_year_month[4:6]) month_index = month -1 month_color = twelve_months_color_list[month_index] for index, row in X.iterrows(): element_count_in_this_cluster = int(row['length']) popup = folium.Popup(year_month, show=True,max_width=400) # show=True代表地图加载时显示 folium.Circle(location=[row['latitude'], row['longitude']], radius=500, popup=popup, color=month_color,fill=True, fill_opacity=0.1).add_to(m) # radius单位是米 #与dbscan半径对应 # folium.Marker(location=[row['latitude'], row['longitude']], popup=popup, icon=folium.Icon(color='red')).add_to(m) #红色标记 url = folium_device_center_save_by_year_circle_html_dir + str(marketer_name) + '_' + str(clock_time_year_month[0:4]) + '.html' m.save(url) except Exception as ex: logger.error("Call method draw_with_folium_by_device_and_year_dbscan_center_circle_style() error!") logger.error("Exception:" + str(ex)) raise ex
def add_h3_legend(m, color_key: dict, title='Legend (draggable!)'): """ Adds a legend for a categorical variable, dislayed by a colored hexagon. :param color_key: dictionary whose keys are the category names and values are the color codes :title: legend title """ macro = MacroElement() macro._template = Template(make_h3_legend_html(color_key, title=title)) m.get_root().add_child(macro) return m
def map(pIndicador): indicador = pIndicador geo_json_data = json.load( open(r'G:\SISMOI\DADOS\vw_indicadores_ceara_simplified100_2.geojson'), encoding='utf8') # ,tiles='Stamen Terrain', tiles='OpenStreetMap' m = folium.Map([-5, -41], zoom_start=7, tiles='OpenStreetMap', control_scale=True) folium.GeoJson(geo_json_data, style_function=lambda feature: { 'fillColor': colorMap[0] if (feature['properties'][colunasIndicadores[indicador]] > 0.0 and feature['properties'][colunasIndicadores[ indicador]] <= 0.2) else colorMap[1] if (feature['properties'][colunasIndicadores[indicador]] > 0.2 and feature['properties'][colunasIndicadores[ indicador]] <= 0.4) else colorMap[2] if (feature['properties'][colunasIndicadores[indicador]] > 0.4 and feature['properties'][colunasIndicadores[ indicador]] <= 0.6) else colorMap[3] if (feature['properties'][colunasIndicadores[indicador]] > 0.6 and feature['properties'][colunasIndicadores[ indicador]] <= 0.8) else colorMap[4], 'color': '#d7d7d7', 'weight': 1 }).add_to(m) macro = MacroElement() s = getLegend(nomesIndicadores[indicador], colorMap) macro._template = Template(s) m.get_root().add_child(macro) ''' folium.map.Marker( [-5, -41], icon=DivIcon( icon_size=(150,36), icon_anchor=(0,0), html='<div style="font-size: 24pt">Test</div>', ) ).add_to(m) ''' m m.save(r'C:\inetpub\wwwroot\sismoi.html')
def __init__(self, data, **kwargs): """Create a Crossfilter Returns ------- Folium Crossfilter Object """ super(Crossfilter, self).__init__(**kwargs) self._name = 'Crossfilter' self.data = data crossfilter_def = MacroElement() crossfilter_def._template = Template((""" {% macro script(this, kwargs) %} var {{this._parent.get_name()}} = {}; {{this._parent.get_name()}}.data = {{this._parent.data}}; {{this._parent.get_name()}}.crossfilter = crossfilter({{this._parent.get_name()}}.data); {{this._parent.get_name()}}.allDim = {{this._parent.get_name()}}.crossfilter.dimension( function(d) {return d;}); {% endmacro %} """)) # noqa self.add_child(crossfilter_def) self._template = Template(u""" {% macro header(this, kwargs) %} <style> #{{this.get_name()}} { {% if this.position %}position : {{this.position}};{% endif %} {% if this.width %}width : {{this.width[0]}}{{this.width[1]}};{% endif %} {% if this.height %}height: {{this.height[0]}}{{this.height[1]}};{% endif %} {% if this.left %}left: {{this.left[0]}}{{this.left[1]}};{% endif %} {% if this.top %}top: {{this.top[0]}}{{this.top[1]}};{% endif %} </style> {% endmacro %} {% macro html(this, kwargs) %} <div id="{{this.get_name()}}"> {{this.html.render(**kwargs)}} </div> {% endmacro %} {% macro script(this, kwargs) %} dc.renderAll(); {% endmacro %} """)
def __init__(self, data, **kwargs): """Create a Crossfilter Returns ------- Folium Crossfilter Object """ super(Crossfilter, self).__init__(**kwargs) self._name = 'Crossfilter' self.data = data crossfilter_def = MacroElement() crossfilter_def._template = Template((""" {% macro script(this, kwargs) %} var {{this._parent.get_name()}} = {}; {{this._parent.get_name()}}.data = {{this._parent.data}}; {{this._parent.get_name()}}.crossfilter = crossfilter({{this._parent.get_name()}}.data); {{this._parent.get_name()}}.allDim = {{this._parent.get_name()}}.crossfilter.dimension( function(d) {return d;}); {% endmacro %} """)) # noqa self.add_child(crossfilter_def) self._template = Template(u""" {% macro header(this, kwargs) %} <style> #{{this.get_name()}} { {% if this.position %}position : {{this.position}};{% endif %} {% if this.width %}width : {{this.width[0]}}{{this.width[1]}};{% endif %} {% if this.height %}height: {{this.height[0]}}{{this.height[1]}};{% endif %} {% if this.left %}left: {{this.left[0]}}{{this.left[1]}};{% endif %} {% if this.top %}top: {{this.top[0]}}{{this.top[1]}};{% endif %} </style> {% endmacro %} {% macro html(this, kwargs) %} <div id="{{this.get_name()}}"> {{this.html.render(**kwargs)}} </div> {% endmacro %} {% macro script(this, kwargs) %} dc.renderAll(); {% endmacro %} """)
def visualize_prediction(df, color_dict, save_to): """[Creates folium map of activity path colored by predicted activity type] Args: df ([pandas df]): [dataframe of activity data including position_lat, position_long and predicted_mode, the predicted activity type] color_dict ([dictionary]): [keys are activity types, values are colors] save_to ([string]): [filepath where folium map is saved] Returns: [folium.Map object]: [folium map of activity path colored by predicted activity type] """ df['break'] = df['predicted_mode'] == df['predicted_mode'].shift(1) df['segment'] = None segment = 0 rows = [] for row in df.to_dict(orient='records'): if not row['break']: row['segment'] = segment segment += 1 rows.append(row) df = pd.DataFrame(rows).fillna(method='ffill') central_lat = df.position_lat.mean() central_long = df.position_long.mean() m = folium.Map(location=[central_lat, central_long], tiles="Stamen Terrain", zoom_start=14.5) for segment in df.segment.unique(): locations = df.query(f"segment=={segment}")[[ 'position_lat', 'position_long' ]] act_type = df.query(f"segment=={segment}")[['predicted_mode' ]].values[0][0] folium.PolyLine(locations.values.tolist(), color=color_dict[act_type], weight=2.5, opacity=0.9).add_to(m) macro = MacroElement() macro._template = Template(legend_helper.legend_string) m.add_child(macro) m.save(save_to) return m
def create_folium_map(venues, lati, longi, id): map = folium.Map([lati, longi], zoom_start=18, control_scale=True) i = 0 color = [ "red", "blue", "green", "gray", "pink", "darkred", "darkpurple", "orange", "purple", "cadetblue" ] popup_text = "" folium.CircleMarker( location=(lati, longi), radius=20, color="green", text="1", fill=True, icon=DivIcon( icon_size=(150, 36), icon_anchor=(7, 20), html='<div style="font-size: 18pt; color : black">1</div>', )).add_child(folium.Popup("AirBnb", parse_html=True, show=True)).add_to(map) htmlText = "" for lat, lon, name, cat in zip(venues['Latitude'], venues['Longitude'], venues['Name'], venues['Category']): popup_text = popup_text.format(i, 12, 12) folium.Marker([lat, lon], popup='', icon=folium.Icon(color=color[i], icon='map-marker-alt')).add_to(map) htmlText = htmlText + '<li style="font-size:12px"><i class="fa fa-map-marker" style="color:' + color[ i] + ';font-size: 5em;"></i> ' + name + ' (' + cat + ')</li>' i += 1 template = get_legend_template(htmlText) macro = MacroElement() macro._template = Template(template) map.get_root().add_child(macro) map.save('./templates/map.html')
def create_map_clusters(data, city, kclusters, zoom=12, rainbow=None): """Create a map with folium, representing the restaurants location and cluster""" if rainbow is None: x = np.arange(kclusters) ys = [i + x + (i * x)**2 for i in range(kclusters)] colors_array = cm.rainbow(np.linspace(0, 1, len(ys))) rainbow = [colors_map.rgb2hex(i) for i in colors_array] template = create_template(kclusters, rainbow) address = city geolocator = Nominatim(user_agent="ny_explorer") location = geolocator.geocode(address) latitude = location.latitude longitude = location.longitude map_clusters = folium.Map(location=[latitude, longitude], zoom_start=zoom) # set color scheme for the clusters # add markers to the map markers_colors = [] for lat, lon, name, poi, cluster in zip(data['latitude'], data['longitude'], data["name"], data['Neighborhood'], data['Cluster Labels']): label = folium.Popup(str(name) + " at " + str(poi), parse_html=True) folium.CircleMarker([lat, lon], radius=5, popup=label, color=rainbow[cluster], fill=True, fill_color=rainbow[cluster], fill_opacity=0.7).add_to(map_clusters) macro = MacroElement() macro._template = Template(template) map_clusters.get_root().add_child(macro) return map_clusters
def add_map_legend(m, title, items): """ Adds a legend for a folium map. Parameters ---------- m : folium.map. Represents a folium map. title : string. Represents the title of the legend. items : list of tuple. Represents the color and name of the legend items. References ---------- https://github.com/python-visualization/folium/issues/528#issuecomment-421445303 """ item = "<li><span style='background:%srs;'></span>%srs</li>" list_items = '\n'.join([item % (c, n) for (n, c) in items]) template = """ {{% macro html(this, kwargs) %}} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() {{ $( "#maplegend" ).draggable({{ start: function (event, ui) {{ $(this).css({{ right: "auto", top: "auto", bottom: "auto" }}); }} }}); }}); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'> {} </div> <div class='legend-scale'> <ul class='legend-labels'> {} </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title {{ text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; }} .maplegend .legend-scale ul {{ margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; }} .maplegend .legend-scale ul li {{ font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; }} .maplegend ul.legend-labels li span {{ display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; }} .maplegend .legend-source {{ font-size: 80%; color: #777; clear: both; }} .maplegend a {{ color: #777; }} </style> {{% endmacro %}}""".format(title, list_items) macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro)
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!')
def map_graph(): # GeoJson Data cluster_gj = gpd.read_file("data/dengue-clusters-geojson.geojson") area_high_ades_gj = gpd.read_file( "data/areas-with-high-aedes-population-geojson.geojson") # Creation of map kw = {"location": [1.3521, 103.8198], "zoom_start": 12} m = folium.Map(**kw) # Styles area_high_ades_style = {"fillColor": "#228B22", "color": "#FF0000"} # Modifying tooltip cluster_gj.Description = cluster_gj.Description.map( lambda x: re.search(r"(<td>.*?</td>)", x).group(0)[4:-5]) area_high_ades_gj.Description = area_high_ades_gj.Description.map( lambda x: re.search(r"(<td>.*?</td>)", x).group(0)[4:-5]) # Addition of layers to map folium.GeoJson( cluster_gj, tooltip=folium.GeoJsonTooltip(fields=["Description"], aliases=["Location"], localize=True), ).add_to(m) folium.GeoJson( area_high_ades_gj, style_function=lambda x: area_high_ades_style, tooltip=folium.GeoJsonTooltip(fields=["Description"], aliases=["Location"], localize=True), ).add_to(m) # Legend # Template from: https://nbviewer.jupyter.org/gist/talbertc-usgs/18f8901fc98f109f2b71156cf3ac81cd template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Legend</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:#73adff;opacity:0.9;'></span>Dengue clusters</li> <li><span style='background:#FF0000;opacity:0.7;'></span>Areas with high ades population</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro) m.save("dengue-cluster.html") return m
def map_legend(col_pilot_dict): from branca.element import Template, MacroElement legend_txt = "" for pilot in col_pilot_dict: legend_txt += ("<li><span style='background:" + col_pilot_dict[pilot] + ";opacity:0.7;'></span>" + pilot + "</li>") first_block = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Legend (draggable)</div> <div class='legend-scale'> <ul class='legend-labels'>""" second_block = """</ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" template = first_block + legend_txt + second_block macro = MacroElement() macro._template = Template(template) return macro
def app(df_clust): st.subheader("Real estate investment") st.markdown( "Imagine that you run a real estate business and you want to invest in Airbnb. This application provides the " "ability to find the most profitable location for your new house. All you have to do is to study the map below " "and click on the specific cluster. This will give you a better intuition of how the prices in different regions of NY city are " "grouped together. In that way we are doing all the \"hard\" work of filtering out the regions which have about the same average price and now you " "are ready to focus on a specific area of NY according to your business plan." ) X_train, X_test, = train_test_split(df_clust, test_size=0.05) df_clustering = X_test.loc[:, X_test.columns.isin(['price', 'zipcode'])] kmeans = KMeans(n_clusters=10, random_state=0) clust = X_test[["latitude", "longitude", 'price', 'zipcode', 'distance']].copy() clust = clust.assign(cluster=kmeans.fit_predict(df_clustering)[:, np.newaxis]) data = clust.copy() ## create color column lst_elements = sorted(list(clust['cluster'].unique())) lst_colors = [ '#8A2BE2', '#FF7F50', '#7FFF00', '#D2691E', '#00FFFF', '#E9967A', '#2F4F4F', '#FF69B4', '#66CDAA', '#FFFF00' ] data["color"] = data['cluster'].apply( lambda x: lst_colors[lst_elements.index(x)]) x = clust.groupby(["cluster"]).mean('price') ## create size column (scaled) scaler = MinMaxScaler(feature_range=(6, 25)) data["size"] = scaler.fit_transform(clust['price'].values.reshape( -1, 1)).reshape(-1) lat = 40.730610 lon = -73.935242 map_hooray = folium.Map([lat, lon], zoom_start=11, tiles="cartodbpositron") ## add points data.apply(lambda row: folium.CircleMarker( location=[row['latitude'], row['longitude']], popup="Price: " + str(round(row['price'])), color=row["color"], fill=True, radius=row["size"]).add_to(map_hooray), axis=1) ## add html legend legend_html = """{% macro html(this, kwargs) %} <div style="position:fixed; bottom:10px; left:10px; border:2px solid black; z-index:9999; font-size:14px;"> <b>""" + 'cluster - average price' + """:</b><br>""" for i in lst_elements: legend_html = legend_html + """ <i class="fa fa-circle fa-1x" style="color:""" + lst_colors[lst_elements.index(i)] + """"> </i> """ + str(i) + """: """ + str(round( x.iloc[i]['price'])) + """<br>""" legend_html = legend_html + """</div> {% endmacro %}""" macro = MacroElement() macro._template = Template(legend_html) map_hooray.add_child(macro) folium_static(map_hooray, width=1000, height=600)
def create_sf_crime_viz(): ''' Load and pre-process the San Francisco crime data ''' # Load the crime data df_crime = pd.read_csv( os.path.join(data_dir_path, 'last_week_SF_crimes.csv')) # Drop the rows in which there's no lat lon data df_crime = df_crime[df_crime['latitude'].notna()] df_crime = df_crime[df_crime['longitude'].notna()] # Create popups and their contents popups_list, locations_list = [], [] for _, row in df_crime.iterrows(): # Trim unnecessary information from the timestamp incident_timestamp = row['incident_datetime'] incident_timestamp = incident_timestamp.replace('T', ' ') incident_timestamp = incident_timestamp[:-7] # Create a popup object and append it to the popups array popup_content = '<strong>Timestamp: </strong>' + incident_timestamp + '<br>' \ + '<strong>Day of the week: </strong>' + row['incident_day_of_week'] + '<br>' \ + '<strong>Description: </strong>' + row['incident_description'] popups_list.append(folium.Popup(html=popup_content)) # Get the lat, lon location data and add it to the list locations_list.append(row[['latitude', 'longitude']].to_numpy().tolist()) ''' Initialize the map ''' map_crime = folium.Map(location=[37.773972, -122.431297], zoom_start=11, max_bounds=True, min_zoom=9, max_lat=38.5, max_lon=-122, min_lat=37, min_lon=-123) ''' Create the map content and add it to the map object ''' # Create marker cluster icon_list = [] for _ in range(len(locations_list)): icon_list.append( folium.Icon(icon='exclamation', prefix='fa', color='orange')) marker_cluster = MarkerCluster(locations=locations_list, popups=popups_list, icons=icon_list) marker_cluster.add_to(map_crime) # Create map legend current_timestamp = datetime.now() - timedelta(days=1) week_before = current_timestamp - timedelta(weeks=1) current_timestamp = current_timestamp.strftime('%Y-%m-%d') week_before = week_before.strftime('%Y-%m-%d') template = utils.create_legend(caption='San Francisco crimes between ' + week_before + ' and ' + current_timestamp) macro = MacroElement() macro._template = Template(template) map_crime.get_root().add_child(macro) ''' Save completed map viz to an appropriate folder ''' map_crime.save( os.path.join(script_dir_path, '..', 'webapp', 'templates', 'SF_crime_viz.html')) print('Successfully created the San Francisco crime viz!')
def create_categorical_legend(map, palette, classnames): """ Function to create and add a categorical legend to a folium map. :param map: folium map to which the legend will be added :param palette: list with color codes for each class :param classnames: list with class names, matching the palette list :return: folium map with categorical legend """ categories = "" # creates class category label to add to legend for ind, cl in enumerate(classnames): categories += f"<li><span style='background:#{palette[ind]};opacity:0.85;'></span>{classnames[cl]}</li>" template_head = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> """ styling = f""" <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Legend</div> <div class='legend-scale'> <ul class='legend-labels'> {categories} </ul> </div> </div> </body> </html> """ end = """ <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" template = template_head + styling + end # Combine all the parts into a single templace docstring macro = MacroElement() macro._template = Template(template) # create an element return map.get_root().add_child( macro) # add element to the map and return the map
margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) html = """ <h3> Event ID : </h3><p>{}</p> <h3> Event Name: </h3><p></p> <h3> Location: </h3><p>{}</p> """ legend_html = """ <div style=”position: fixed; bottom: 50px; left: 50px; width: 100px; height: 90px; border:2px solid grey; z-index:9999; font-size:14px; “> Cool Legend <br> East <i class=”fa fa-map-marker fa-2x” style=”color:green”></i><br>
def generate_location_map(reportfolderbase, legend_title): KML_path = os.path.join(reportfolderbase, iLEAPP_KMLs) if not os.path.isdir(KML_path) or not os.listdir(KML_path): return location_path = os.path.join(reportfolderbase, 'LOCATIONS') os.makedirs(location_path, exist_ok=True) db = sqlite3.connect(os.path.join(KML_path, "_latlong.db")) df = pd.read_sql_query( "SELECT key as Name, Activity as Description, latitude, longitude FROM data ;", db) df["Point"] = df.apply( lambda row: Point(float(row['longitude']), float(row['latitude']), .0), axis=1) #sorting is needed for correct display df.sort_values(by=['Name'], inplace=True) #Parse geo data and add to Folium Map data_names = df[~df.Description.str.contains('Photos')].Description.unique( ) featuresProp = {} for c, d in zip(colors, data_names): descFilter = d if 'ZRT' in d: fType = 'LineString' icon = 'marker' iconUrl = defaultIconUrl.format(c) shadowUrl = defaultShadowUrl else: fType = 'MultiPoint' icon = 'circle' iconUrl = '' shadowUrl = '' color = c featuresProp[d] = { 'fType': fType, 'color': c, 'icon': icon, 'iconUrl': iconUrl, 'shadowUrl': defaultShadowUrl, } location_map = folium.Map([df.iloc[0].Point.y, df.iloc[0].Point.x], prefer_canvas=True, zoom_start=6) bounds = ( df[~df.Description.str.contains('Photos')]['longitude'].min(), df[~df.Description.str.contains('Photos')]['latitude'].min(), df[~df.Description.str.contains('Photos')]['longitude'].max(), df[~df.Description.str.contains('Photos')]['latitude'].max(), ) location_map.fit_bounds([ (bounds[1], bounds[0]), (bounds[3], bounds[2]), ]) tsGeo = TimestampedGeoJson( { 'type': 'FeatureCollection', 'features': [geodfToFeatures(df, f, featuresProp) for f in data_names] }, period="PT1M", duration="PT1H", loop=False, transition_time=50, time_slider_drag_update=True, add_last_point=True, max_speed=200).add_to(location_map) #legend legend = '\n'.join([ legend_tag.format(featuresProp[f]['color'], htmlencode(f)) for f in data_names ]) template = '\n'.join([ template_part1, legend_title_tag.format(htmlencode(legend_title)), legend_div.format(legend), template_part2 ]) macro = MacroElement() macro._template = Template(template) location_map.get_root().add_child(macro) location_map.save(os.path.join(location_path, "Locations_Map.html")) report = ArtifactHtmlReport('Locations Map') report.start_artifact_report(location_path, 'Locations Map', 'Map plotting all locations') report.write_raw_html( open(os.path.join(location_path, "Locations_Map.html")).read()) report.end_artifact_report()
def plot_initial_state(current_df,geojson): # Initiate map m = folium.Map(location=[62, 20], zoom_start=5) # Define styling rules for counties def style_function(feature): d = feature['properties']['name'] if current_df.at[d,"Rate"] < 0.5: if current_df.at[d,"SurplusCapacity"] > 3: color = '#7AA826' #green else: color = '#FFCA2D' #yellow elif 0.5 <= current_df.at[d,"Rate"] < 0.9: color='#FFCA2D' #yellow elif 0.9 <= current_df.at[d,"Rate"] <= 1: color='#EA830E' #orange elif 1 < current_df.at[d,"Rate"]: color='#BF2C2A' #red return {'fillOpacity': 0.4,'weight': 0.5, 'color': 'black','fillColor': color} # Import geojson data and apply styling rule folium.GeoJson( geojson, name='geojson', style_function=style_function ).add_to(m) # Add a clickable circle to each county for idx, row in current_df.iterrows(): # Define styling rules if row.Rate < 0.5: if row.SurplusCapacity > 3: color = '#7AA826' #green else: color = '#FFCA2D' #yellow elif 0.5 <= row.Rate < 0.9: color='#FFCA2D' #yellow elif 0.9 <= row.Rate <= 1: color='#EA830E' #orange elif 1 < row.Rate: color='#BF2C2A' #red # Draw circle folium.Circle( radius= 7000 + row.IVA*200, location=[row.Lat, row.Long], popup=folium.Popup('<b>'+row.Region+'</b><br>'+\ '<br>Patienter: '+str(row.IVA)+\ '<br>Kapacitet: '+str(row.Capacity), max_width=450,min_width=150), color=color, fill=True, fill_color=color, tooltip="Klicka här!", ).add_to(m) from branca.element import Template, MacroElement template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Color code explanation</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:#BF2C2A;opacity:0.7;'></span>Over 100% of capacity</li> <li><span style='background:#EA830E;opacity:0.7;'></span>Between 90% and 100% of capacity</li> <li><span style='background:#FFCA2D;opacity:0.7;'></span>Between 50% and 90% of capacity</li> <li><span style='background:#7AA826;opacity:0.7;'></span>Less than 50% of capacity</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro) return m
def generate_map_legend() -> MacroElement: """ Generates a legend for the map. :return: MacroElement, html added to the map """ template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Dashboard</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> </head> <body> <div id='maplegend' class='maplegend' style=' position: absolute; z-index:9999; background-color:rgba(255, 255, 255, 0.8); border: 1px solid #D4D4D4; border-radius:6px; padding: 10px; font-size:14px; right: 10px; bottom: 23px; '> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:#E87272;'></span>Unspecified</li> <li><span style='background:#7a0091;'></span>Navigation</li> <li><span style='background:#11498A;'></span>Fishing</li> <li><span style='background:#1A6D9B;'></span>Tug</li> <li><span style='background:#12A5B0;'></span>Passenger</li> <li><span style='background:#3A9971;'></span>Cargo</li> <li><span style='background:#79BD00;'></span>Tanker</li> <li><span style='background:#DBB657;'></span>Pleasure</li> </ul> </div> </div> </body> </html> <style type='text/css'> * { font-family: "Roboto", sans-serif; } .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } .maplegend .legend-scale ul:last-child { margin-bottom: 0px; } .maplegend .legend-scale ul li:last-child { margin-bottom: 0px; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) return macro
def geographic_graph(regional): """ function that plots the geographic_graph of a variable in a specific date of all the regions in your regional dataframe open a browser's tab for showing the map requested don't :return: """ variables = regional.columns[::] variables = variables.delete([0, 1, 2, 3, 4, 5, 20, 22, 23]) my_date = verify_date(regional) obs = variables_pool(variables, "Insert variable to analyze") regional["data"] = regional["data"].str[0:10] entries = regional["data"] == str(my_date) list_value = regional[entries][obs].tolist() longitudini = regional["long"].tolist()[:21] latitudini = regional["lat"].tolist()[:21] nomi = regional["denominazione_regione"].tolist()[:21] color = [] for k in range(0, len(list_value)): if math.isnan(list_value[k]) or list_value[k] == 0: list_value[k] = 0 color.append("green") else: color.append("crimson") try: alfa = max(list_value) omega = 50000 scaled_value_list = [] for i in range(0, len(list_value)): equation = (list_value[i] * omega) / alfa scaled_value_list.append(equation) except ZeroDivisionError: scaled_value_list = [0] * len(list_value) print("[!] Value not defined in this date") m = folium.Map(location=[41.87194, 12.56738], tiles="CartoDB positron", min_zoom=5.8, max_zoom=7, zoom_start=5.8, zoom_control=True, min_lat=36, max_lat=47, min_lon=9.5, max_lon=15.5, max_bounds=True) for i in range(0, len(list_value)): list_value[i] = int(list_value[i]) folium.Circle(location=(latitudini[i], longitudini[i]), popup=nomi[i] + "\n" + obs.replace("_", " ").capitalize() + ": " + str(list_value[i]), radius=scaled_value_list[i], color=color[i], fill=True, fill_color='crimson').add_to(m) template1 = " {% macro html(this, kwargs) %} <!doctype html> <html lang=\"en\"> <head> <meta charset=\"utf-8\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <title>ITALY COVID-19</title> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>" template = "Data: %s</div>" % str(my_date) template = template1 + template template = template + " <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:red;opacity:0.7;'></span>Valore presente</li> <li><span style='background:green;opacity:0.7;'></span>Valore non presente</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {" "" + """%""" + " endmacro %}" macro = MacroElement() macro._template = Template(template) m.add_child(macro) m.save("data" + os.sep + "%s_italy_%s.html" % (str(my_date), obs)) webbrowser.open_new_tab("data" + os.sep + "%s_italy_%s.html" % (str(my_date), obs))
def legend(map): '''Funtion to create a custom Folium map legend using branca.element class Parameters: ----------- map (folium.folium.Map): Folium Map Object Returns: -------- no returns ''' template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 2px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Legend (draggable!)</div> <div class="container"> <div class="left"> <p> <b>Hotpots 24 hours</b> </p> </div> <div class="right"> <img width="30" height="30" src="icons/fire24.png" alt="fire 24h"/> </div> </div> <div class="container"> <div class="left"> <p> <b>Hotpots 48 hours</b> </p> </div> <div class="right"> <img width="30" height="30" src="icons/fire48.png" alt="fire 48h"/> </div> </div> <div class="container"> <div class="left"> <p> <b>Hotpots 7 days</b> </p> </div> <div class="right"> <img width="30" height="30" src="icons/fire7d.png" alt="fire 7d"/> </div> </div> <br> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; font-weight: bold; font-size: 90%; } .maplegend a { color: #777; } .container { width:150px; display:table; margin-bottom: -15px; padding: 2px; } .container > div { display:table-cell; } .container > div p { margin:0; } .container .left { text-align:left; font-size: 80%; color: #777; clear: both; vertical-align: bottom; } .container .right { text-align:center; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) map.get_root().add_child(macro)
def quick_geo_plot(): import pandas as pd """Import Data""" file_i = '/Users/Derrick-Vlad-/Desktop/Output_Trail_1/Clean/v1.1/' + 'Quick_Geoplot_Filtered_LATEST.csv' df = pd.read_csv(file_i, sep=',', encoding='unicode_escape') """Filter Data""" #df = df[df['latitude'] != 'UnableToFind'] #df = df[(df['Latitude'].astype(float) < 2.0) & (df['Longitude'].astype(float) < 104.0)] print(df[['Latitude', 'Longitude']].head()) df = df[['Latitude', 'Longitude', 'Price ($)']] df = df.convert_objects(convert_numeric=True).dropna() print(df['Latitude'].dtype) print(df['Longitude'].dtype) print(df['Price ($)'].dtype) """Base Map""" import folium from folium.plugins import HeatMap def generateBaseMap(default_location=[1.3521, 103.8198], default_zoom_start=12): base_map = folium.Map(location=default_location, control_scale=True, zoom_start=default_zoom_start) return base_map base_map = generateBaseMap() """Prep Data""" d = df[['Longitude', 'Latitude', 'Price ($)']].values.tolist() from folium import plugins """Customize Heat-Map""" # This gradient = {.6: 'blue', .98: 'lime', 1: 'red'} # Original # Or This # import branca.colormap as cm # steps = 10 # color_map = cm.LinearColormap('RGB').scale(0, 1).to_step(steps) # gradient = {} # for i in range(steps): # gradient[1 / steps * i] = color_map.rgb_hex_str(1 / steps * i) max_amount = df['Price ($)'].max() m = plugins.HeatMap(d, radius=11, min_opacity=0.1, max_zoom=1, blur=12, max_val=max_amount, gradient=gradient).add_to(base_map) """Customize LEGEND""" from branca.element import Template, MacroElement template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Legend (draggable!)</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:red;opacity:0.7;'></span>High Priced</li> <li><span style='background:lime;opacity:0.7;'></span>Medium Priced</li> <li><span style='background:blue;opacity:0.7;'></span>Relatively Low Priced</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro) m.save('Geo_Plot.html') import webbrowser, os webbrowser.open('file://' + os.path.realpath('index.html')) #quick_geo_plot()
def index(): # UP Diliman coordinates start_coords = (14.6538, 121.0685) macro = MacroElement() # Geojson data route = os.path.join('map_data', 'route.json') # initialize excel file for data writing wb = Workbook() ws = wb.active ws['A1'] = 'Case number' ws['B1'] = '# of Passengers' ws['C1'] = 'Radial Parameter Pass (m)' ws['D1'] = '# of Drivers' ws['E1'] = 'Radial Parameter Driver (m)' ws['F1'] = 'Route Length (km)' ws['G1'] = 'Route Time (minutes)' ws['H1'] = '# of Matches' ws['I1'] = 'Trip Price (Php)' ws['J1'] = 'SRPs' ws['K1'] = 'SRPs' ws['L1'] = 'SRPs' ws['M1'] = 'Average SRP' ws['N1'] = 'Processing time (seconds)' ws['O1'] = 'Route Length (km)' ws['P1'] = 'Route Time (minutes)' ws['Q1'] = '# of Matches' ws['R1'] = 'Trip Price (Php)' ws['S1'] = 'SRPs' ws['T1'] = 'SRPs' ws['U1'] = 'SRPs' ws['V1'] = 'Average SRP' ws['W1'] = 'Angle' ws['X1'] = 'Processing time (seconds)' # passengers = ['30763177','5585622052','30763115'] # passenger_destinations = ['17216442','2517360527','2517360522'] # drivers = ['30763220','1402297896','5499240548'] # passengers = ['5446811375','29025439','17216409'] # passenger_destinations = ['17216442','2517360527','2517360522'] # drivers = ['30763220','1402297896','5499240548'] passengers = load_object('passenger_sources.pkl') passenger_destinations = load_object('passenger_destinations.pkl') drivers = load_object('driver_locations.pkl') pass_radii = load_object('rand_pass_radii.pkl') dri_radii = load_object('rand_dri_radii.pkl') # ctr = 0 row_excel = 2 main_ctr = 0 while main_ctr < 300: a = ws.cell(row = row_excel, column = 1) a.value = main_ctr+1 a = ws.cell(row = row_excel, column = 2) a.value = len(passengers[main_ctr]) a = ws.cell(row = row_excel, column = 3) a.value = pass_radii[main_ctr] a = ws.cell(row = row_excel, column = 4) a.value = len(drivers[main_ctr]) a = ws.cell(row = row_excel, column = 5) a.value = dri_radii[main_ctr] folium_map = folium.Map(location=start_coords,zoom_start=16,height='85%') # searchbased-rs implementation ------------------ start_time = time.perf_counter() sources, destinations, path, route_distance, route_time, fare, srp_list = searchbasedRS('adj_list_obj.pkl', drivers[main_ctr], passengers[main_ctr], passenger_destinations[main_ctr], 0.5, row_excel) end_time = time.perf_counter() print('\nSearch-BasedRS time elapsed (seconds): ' + str(end_time - start_time) + '\n') if sources != None: a = ws.cell(row = row_excel, column = 6) a.value = route_distance a = ws.cell(row = row_excel, column = 7) a.value = route_time a = ws.cell(row = row_excel, column = 8) a.value = len(sources) a = ws.cell(row = row_excel, column = 9) a.value = fare srp_column = 10 for srp in srp_list: a = ws.cell(row = row_excel, column = srp_column) a.value = srp srp_column += 1 a = ws.cell(row = row_excel, column = 14) a.value = end_time - start_time # ------------------------------------------------ # save html file for searchbased # ----------------------------------------------------------------------- # driver_coordinates = get_coordinates('nodes_coordinates.pkl', drivers[main_ctr]) for driver_coordinate in driver_coordinates: # folium.Marker(driver_coordinate, tooltip='Driver', icon=folium.Icon(color='red', icon='user')).add_to(folium_map), # Create custom marker icon car_icon = folium.features.CustomIcon('map_data/car_marker.png', icon_size=(40, 40)) folium.Marker(driver_coordinate,icon=car_icon).add_to(folium_map), # # add additional markers and path if match/es found if sources!=None: # add path coordinates = get_coordinates('nodes_coordinates.pkl', path) way_sample=folium.PolyLine(locations=coordinates,weight=5,color = 'red') folium_map.add_child(way_sample) # Create markers for matched sources and destinations # markers for other available passengers shown # All drivers will have a marker to mimic actual ride sharing applications coordinates_pass = get_coordinates('nodes_coordinates.pkl', passengers[main_ctr]) for passenger in coordinates_pass: if passenger in coordinates: continue icon_color = 'beige' folium.Marker(passenger, tooltip='Source', icon=folium.Icon(color=icon_color, icon='user')).add_to(folium_map), ctr = 0 for source in sources: index = path.index(source) if ctr == 0: icon_color = 'blue' elif ctr == 1: icon_color = 'green' elif ctr == 2: icon_color = 'purple' folium.Marker(coordinates[index], tooltip='Source', icon=folium.Icon(color=icon_color, icon='chevron-up')).add_to(folium_map), ctr+=1 ctr = 0 for destination in destinations: index = path.index(destination) if ctr == 0: icon_color = 'blue' elif ctr == 1: icon_color = 'green' elif ctr == 2: icon_color = 'purple' folium.Marker(coordinates[index], tooltip='Destination', icon=folium.Icon(color=icon_color, icon='chevron-down')).add_to(folium_map), ctr+=1 # add legend if len(sources) == 1: macro._template = Template(template1) folium_map.get_root().add_child(macro) elif len(sources) == 2: macro._template = Template(template2) folium_map.get_root().add_child(macro) else: macro._template = Template(template3) folium_map.get_root().add_child(macro) # # Geojson overlay # folium.GeoJson(route, name='route').add_to(folium_map) fn='templates/map.html' fn = fn.replace(fn, 'templates/map' + str(main_ctr) + '_search.html') folium_map.save(fn) folium_map = folium.Map(location=start_coords,zoom_start=16,height='85%') # # grab algorithm implementation ------------------ start_time = time.perf_counter() sources, destinations, path, route_distance, route_time, fare, srp_list, angle = grab_share('adj_list_obj.pkl', drivers[main_ctr], passengers[main_ctr], passenger_destinations[main_ctr], 60) end_time = time.perf_counter() print('\nGrabShare Algorithm time elapsed (seconds): ' + str(end_time - start_time) + '\n') if sources != None: a = ws.cell(row = row_excel, column = 15) a.value = route_distance a = ws.cell(row = row_excel, column = 16) a.value = route_time a = ws.cell(row = row_excel, column = 17) a.value = len(sources) a = ws.cell(row = row_excel, column = 18) a.value = fare srp_column = 19 for srp in srp_list: a = ws.cell(row = row_excel, column = srp_column) a.value = srp srp_column += 1 a = ws.cell(row = row_excel, column = 23) a.value = angle a = ws.cell(row = row_excel, column = 24) a.value = end_time - start_time # save html file for grab # ----------------------------------------------------------------------- # driver_coordinates = get_coordinates('nodes_coordinates.pkl', drivers[main_ctr]) for driver_coordinate in driver_coordinates: # folium.Marker(driver_coordinate, tooltip='Driver', icon=folium.Icon(color='red', icon='user')).add_to(folium_map), # Create custom marker icon car_icon = folium.features.CustomIcon('map_data/car_marker.png', icon_size=(40, 40)) folium.Marker(driver_coordinate,icon=car_icon).add_to(folium_map), # # add additional markers and path if match/es found if sources!=None: # add path coordinates = get_coordinates('nodes_coordinates.pkl', path) way_sample=folium.PolyLine(locations=coordinates,weight=5,color = 'red') folium_map.add_child(way_sample) # Create markers for matched sources and destinations # markers for other available passengers shown # All drivers will have a marker to mimic actual ride sharing applications coordinates_pass = get_coordinates('nodes_coordinates.pkl', passengers[main_ctr]) for passenger in coordinates_pass: if passenger in coordinates: continue icon_color = 'beige' folium.Marker(passenger, tooltip='Source', icon=folium.Icon(color=icon_color, icon='user')).add_to(folium_map), ctr = 0 for source in sources: index = path.index(source) if ctr == 0: icon_color = 'blue' elif ctr == 1: icon_color = 'green' elif ctr == 2: icon_color = 'purple' folium.Marker(coordinates[index], tooltip='Source', icon=folium.Icon(color=icon_color, icon='chevron-up')).add_to(folium_map), ctr+=1 ctr = 0 for destination in destinations: index = path.index(destination) if ctr == 0: icon_color = 'blue' elif ctr == 1: icon_color = 'green' elif ctr == 2: icon_color = 'purple' folium.Marker(coordinates[index], tooltip='Destination', icon=folium.Icon(color=icon_color, icon='chevron-down')).add_to(folium_map), ctr+=1 # add legend if len(sources) == 1: macro._template = Template(template1) folium_map.get_root().add_child(macro) elif len(sources) == 2: macro._template = Template(template2) folium_map.get_root().add_child(macro) else: macro._template = Template(template3) folium_map.get_root().add_child(macro) # # Geojson overlay # folium.GeoJson(route, name='route').add_to(folium_map) fn='templates/map.html' fn = fn.replace(fn, 'templates/map' + str(main_ctr) + '_grab.html') folium_map.save(fn) # # ------------------------------------------------ row_excel += 1 main_ctr += 1 wb.save('data.xlsx') return render_template('index.html')
def create_legend(folium_object, service, events, hostelry): template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 470px; bottom: 100px;'> <div class='legend-title'>Legend</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:#400D79;opacity:0.7;'></span>Companies</li> <li><span style='background:#3386FF;opacity:0.7;'></span>""" + service.title( ) + """s</li> <li><span style='background:#158E34;opacity:0.7;'></span>""" + events.title( ) + """ events</li> <li><span style='background:#F97100;opacity:0.7;'></span>""" + hostelry.title( ) + """</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) folium_object.get_root().add_child(macro) folium_object.save('../output/map_folium.html') # save map as html return folium_object
def plot_to_map( camera_pano_path, mountains_in_sight, coordinates, filename, dem_file, converter, locs=None, mountains=None, images=None, ): p_i("Creating Interactive Map") c_lat, c_lon, _, _ = coordinates ll, ul, ur, lr = location_handler.get_raster_bounds(dem_file) load_dotenv() MAPBOX_TOKEN = os.getenv("MAPBOX_TOKEN") MAPBOX_STYLE_URL = os.getenv("MAPBOX_STYLE_URL") m = folium.Map( [c_lat, c_lon], tiles=None, zoom_start=12, scrollWheelZoom=False, ) folium.TileLayer( location=[c_lat, c_lon], tiles=MAPBOX_STYLE_URL, API_key=MAPBOX_TOKEN, attr="Christian Hein", name="Settings", ).add_to(m) min_ele, max_ele = 10000, 0 for i in mountains: if i.location.elevation > max_ele: max_ele = i.location.elevation if i.location.elevation < min_ele: min_ele = i.location.elevation ########################################################################### ########################################################################### # All mountains in dataset if mountains: mountains_fg = folium.FeatureGroup(name="All Mountains", show=False) m.add_child(mountains_fg) [(folium.Marker( location=(i.location.latitude, i.location.longitude), popup="%s\n%im" % ( str(i.name), i.location.elevation, ), icon=folium.DivIcon(html=get_glyph( f"am-{i.name}-{int(i.location.elevation)}", "#755239", i.location.elevation, min_ele, max_ele)), zIndexOffset=1, ).add_to(mountains_fg)) for i in mountains] ########################################################################### ########################################################################### # Mountains in sight if mountains_in_sight: mountains_in_sight_fg = folium.FeatureGroup(name="Visible Mountains", show=True) m.add_child(mountains_in_sight_fg) [(folium.Marker( location=(i.location.latitude, i.location.longitude), popup="%s\n%im" % ( str(i.name), i.location.elevation, ), icon=folium.DivIcon(html=get_glyph( f"vm-{i.name}-{int(i.location.elevation)}", "#426877", i.location.elevation, min_ele, max_ele)), zIndexOffset=10, ).add_to(mountains_in_sight_fg)) for i in mountains_in_sight] ########################################################################### ########################################################################### # Other images in dataset if images: images_fg = folium.FeatureGroup(name="Visible Images", show=True) m.add_child(images_fg) for im in images: encoded = base64.b64encode(open(im.thumbnail_path, "rb").read()) html = f''' <!doctype html> <html> <head> <style> .redirect-button {{ color: #fff; cursor: pointer; background-color: #6c757d; border-color: #6c757d; display: inline-block; font-weight: 400; line-height: 1.5; text-align: center; text-decoration: none; vertical-align: middle; padding: .375rem .75rem; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; }} .redirect-button:hover {{ color: #fff; background-color: #5c636a; border-color: #545b62; }} </style> <script type="text/javascript"> function redirect() {{ console.log("Redirecting to: ", "{im.name}"); window.parent.parent.postMessage("{im.name}", '*'); }} </script> </head> <body> <button class="redirect-button" onclick="redirect();">View image</button> <img src="data:image/JPG;base64,{encoded.decode("UTF-8")}"> </body> </html> ''' iframe = folium.IFrame(html, width=450 + 20, height=150 + 20) popup = folium.Popup(iframe, max_width=470) folium.Marker( location=(im.location.latitude, im.location.longitude), popup=popup, icon=folium.Icon(color="orange", icon="camera"), zIndexOffset=12, ).add_to(images_fg) ########################################################################### ########################################################################### # Current viewpoint encoded = base64.b64encode(open(camera_pano_path, "rb").read()) html = f''' <!doctype html> <html> <img src="data:image/JPG;base64,{encoded.decode("UTF-8")}"> </html> ''' iframe = folium.IFrame(html, width=450 + 20, height=150 + 20) popup = folium.Popup(iframe, max_width=450) folium.Marker( location=[c_lat, c_lon], popup=popup, icon=folium.Icon(color="green", icon="camera"), zIndexOffset=13, ).add_to(m) ########################################################################### ########################################################################### # Visible coordinates if locs: locs_fg = folium.FeatureGroup(name="Retrieved Coordinates", show=True) m.add_child(locs_fg) for i in locs: loc = converter.convert(*i) folium.Circle( location=(loc.latitude, loc.longitude), color="#0a6496", fill=True, fill_color="#0a6496", fill_opacity=1, radius=15, ).add_to(locs_fg) ########################################################################### ########################################################################### # Raster bounds raster_bounds = folium.FeatureGroup(name="Raster Bounds", show=False) m.add_child(raster_bounds) folium.PolyLine(locations=[ll, ul, ur, lr, ll], color="#d63e29", zIndexOffset=15).add_to(raster_bounds) ########################################################################### ########################################################################### # Legend template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px 10px 1px; font-size:16px; font-weight:500; right: 20px; bottom: 24px;'> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:#71b025;opacity:1.0;'></span>Current Viewpoint</li> <li><span style='background:#f69730;opacity:1.0;'></span>Images in dataset</li> <li><span style='background:#755239;opacity:1.0;'></span>All mountains in dataset</li> <li><span style='background:#426877;opacity:1.0;'></span>Mountains in sight</li> <li><span style='background:#d63e29;opacity:1.0;'></span>DEM bounding box</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) ########################################################################### ########################################################################### # Add to map folium.LayerControl().add_to(m) m.get_root().add_child(macro) # m.add_child(Fullscreen(position='topleft')) m.save(filename)
def add_legend( self, title="Legend", colors=None, labels=None, legend_dict=None, builtin_legend=None, opacity=1.0, **kwargs, ): """Adds a customized basemap to the map. Reference: https://bit.ly/3oV6vnH Args: title (str, optional): Title of the legend. Defaults to 'Legend'. Defaults to "Legend". colors ([type], optional): A list of legend colors. Defaults to None. labels ([type], optional): A list of legend labels. Defaults to None. legend_dict ([type], optional): A dictionary containing legend items as keys and color as values. If provided, legend_keys and legend_colors will be ignored. Defaults to None. builtin_legend ([type], optional): Name of the builtin legend to add to the map. Defaults to None. opacity (float, optional): The opacity of the legend. Defaults to 1.0. """ import pkg_resources from branca.element import MacroElement, Template pkg_dir = os.path.dirname( pkg_resources.resource_filename("geemap", "geemap.py") ) legend_template = os.path.join(pkg_dir, "data/template/legend.txt") if not os.path.exists(legend_template): raise FileNotFoundError("The legend template does not exist.") if labels is not None: if not isinstance(labels, list): raise ValueError("The legend labels must be a list.") else: labels = ["One", "Two", "Three", "Four", "etc"] if colors is not None: if not isinstance(colors, list): raise ValueError("The legend colors must be a list.") elif all(isinstance(item, tuple) for item in colors): try: colors = ["#" + rgb_to_hex(x) for x in colors] except Exception as e: raise Exception(e) elif all((item.startswith("#") and len(item) == 7) for item in colors): pass elif all((len(item) == 6) for item in colors): pass else: raise ValueError("The legend colors must be a list of tuples.") else: colors = ["#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", "#80B1D3"] if len(labels) != len(colors): raise ValueError("The legend keys and values must be the same length.") allowed_builtin_legends = builtin_legends.keys() if builtin_legend is not None: if builtin_legend not in allowed_builtin_legends: raise ValueError( "The builtin legend must be one of the following: {}".format( ", ".join(allowed_builtin_legends) ) ) else: legend_dict = builtin_legends[builtin_legend] labels = list(legend_dict.keys()) colors = list(legend_dict.values()) if all(isinstance(item, tuple) for item in colors): try: colors = [rgb_to_hex(x) for x in colors] except Exception as e: raise Exception(e) elif all(isinstance(item, str) for item in colors): colors = ["#" + color for color in colors] if legend_dict is not None: if not isinstance(legend_dict, dict): raise ValueError("The legend dict must be a dictionary.") else: labels = list(legend_dict.keys()) colors = list(legend_dict.values()) if all(isinstance(item, tuple) for item in colors): try: colors = [rgb_to_hex(x) for x in colors] except Exception as e: raise Exception(e) elif all(isinstance(item, str) for item in colors): colors = ["#" + color for color in colors] content = [] with open(legend_template) as f: lines = f.readlines() for index, line in enumerate(lines): if index < 36: content.append(line) elif index == 36: line = lines[index].replace("Legend", title) content.append(line) elif index < 39: content.append(line) elif index == 39: for i, color in enumerate(colors): item = f" <li><span style='background:{check_color(color)};opacity:{opacity};'></span>{labels[i]}</li>\n" content.append(item) elif index > 41: content.append(line) template = "".join(content) macro = MacroElement() macro._template = Template(template) self.get_root().add_child(macro)
def add_map_legend(m: Map, title: str, items: tuple | Sequence[tuple]): """ Adds a legend for a folium map. Parameters ---------- m : Map Represents a folium map. title : str Represents the title of the legend items : list of tuple Represents the color and name of the legend items References ---------- https://github.com/python-visualization/folium/issues/528#issuecomment-421445303 Examples -------- >>> import folium >>> from pymove.utils.visual import add_map_legend >>> df lat lon datetime id 0 39.984094 116.319236 2008-10-23 05:53:05 1 1 39.984198 116.319322 2008-10-23 05:53:06 1 2 39.984224 116.319402 2008-10-23 05:53:11 1 3 39.984211 116.319389 2008-10-23 05:53:16 2 4 39.984217 116.319422 2008-10-23 05:53:21 2 >>> m = folium.Map(location=[df.lat.median(), df.lon.median()]) >>> folium.PolyLine(mdf[['lat', 'lon']], color='red').add_to(m) >>> pm.visual.add_map_legend(m, 'Color by ID', [(1, 'red')]) >>> m.get_root().to_dict() { "name": "Figure", "id": "1d32230cd6c54b19b35ceaa864e61168", "children": { "map_6f1abc8eacee41e8aa9d163e6bbb295f": { "name": "Map", "id": "6f1abc8eacee41e8aa9d163e6bbb295f", "children": { "openstreetmap": { "name": "TileLayer", "id": "f58c3659fea348cb828775f223e1e6a4", "children": {} }, "poly_line_75023fd7df01475ea5e5606ddd7f4dd2": { "name": "PolyLine", "id": "75023fd7df01475ea5e5606ddd7f4dd2", "children": {} } } }, "map_legend": { # legend element "name": "MacroElement", "id": "72911b4418a94358ba8790aab93573d1", "children": {} } }, "header": { "name": "Element", "id": "e46930fc4152431090b112424b5beb6a", "children": { "meta_http": { "name": "Element", "id": "868e20baf5744e82baf8f13a06849ecc", "children": {} } } }, "html": { "name": "Element", "id": "9c4da9e0aac349f594e2d23298bac171", "children": {} }, "script": { "name": "Element", "id": "d092078607c04076bf58bd4593fa1684", "children": {} } } """ item = "<li><span style='background:%s;'></span>%s</li>" list_items = '\n'.join([item % (c, n) for (n, c) in items]) template = """ {{% macro html(this, kwargs) %}} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() {{ $( "#maplegend" ).draggable({{ start: function (event, ui) {{ $(this).css({{ right: "auto", top: "auto", bottom: "auto" }}); }} }}); }}); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'> {} </div> <div class='legend-scale'> <ul class='legend-labels'> {} </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title {{ text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; }} .maplegend .legend-scale ul {{ margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; }} .maplegend .legend-scale ul li {{ font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; }} .maplegend ul.legend-labels li span {{ display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; }} .maplegend .legend-source {{ font-size: 80%; color: #777; clear: both; }} .maplegend a {{ color: #777; }} </style> {{% endmacro %}}""".format(title, list_items) macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro, name='map_legend')
def return_and_save_bike_station_map(df, station_location): """Function which returns a map of bike stations. Parameters ---------- df : dataframe a dataframe which contains all data from the bikeshare rental company Capital Bike station_location : dataframe a dataframe which contains all Terminal IDs to bike rental stations from Capital Bike Returns ------- map returns a folium html map with a draggable legend """ if len(df["Start station number"].unique()) == len( df["End station number"].unique()): pass else: return False unique_stats = (pd.DataFrame({ "Start station number": (df["Start station number"].unique()) }).merge(pd.DataFrame({ "NO_OF_BIKES": (df.groupby(["Start station number"]).count()["Bike number"]) }), on="Start station number", how="left").rename( columns={"Start station number": "TERMINAL_NUMBER"})) unique_stats["color"] = pd.cut(unique_stats['NO_OF_BIKES'], bins=3, labels=['green', 'orange', 'red']) cuts = pd.cut(unique_stats['NO_OF_BIKES'], bins=3, retbins=True, labels=['green', 'orange', 'red']) station_loc_full = pd.merge(unique_stats, station_location[[ "TERMINAL_NUMBER", "LONGITUDE", "LATITUDE", "ADDRESS" ]], on="TERMINAL_NUMBER") m = folium.Map(location=[ ((station_loc_full.LATITUDE.min() + station_loc_full.LATITUDE.max()) / 2), ((station_loc_full.LONGITUDE.min() + station_loc_full.LONGITUDE.max()) / 2) ], zoom_start=12, no_touch=True, control_scale=True) template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'> <div class='legend-title'>Legend of usage over two years</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:red;opacity:0.7;'></span> High usage (""" + str( round(cuts[1][2])) + """ to """ + str(round(cuts[1][3])) + """)</li> <li><span style='background:orange;opacity:0.7;'></span>Medium usage (""" + str( round(cuts[1][1])) + """ to """ + str(round( cuts[1][2])) + """)</li> <li><span style='background:green;opacity:0.7;'></span>Small usage (0 to """ + str( round(cuts[1][1])) + """)</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) for i in range(0, len(station_loc_full) - 1): folium.Marker([ station_loc_full["LATITUDE"][i], station_loc_full["LONGITUDE"][i] ], icon=folium.Icon(color=station_loc_full["color"][i], icon="bicycle", prefix='fa')).add_to(m) m = m.get_root().add_child(macro) return m
def template_macro(date): template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { $( "#maplegend" ).draggable({ start: function (event, ui) { $(this).css({ right: "auto", top: "auto", bottom: "auto" }); } }); }); </script> </head> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:0px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 20px; font-size:32px; right: 20px; bottom: 20px;'> <div class='legend-title'>"""+date+\ """</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:blue;opacity:0.7;'></span> Verkehr</li> <li><span style='background:#E37222;opacity:0.7;'></span>Stickstoffdioxid NO2</li> <li><span style='background:#808080;opacity:0.7;'></span>Regressionsmodell</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 10px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 12px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 0px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) return macro
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!')
def add_html(m): template = """ {% macro html(this, kwargs) %} <!doctype html> <html lang="en"> <body> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:0px solid grey;; background-color:rgba(255, 255, 255, 0.9); border-radius:6px; padding: 0px; left: 50px; top: 11px;'> <div class='home-button'><a href="https://my-heatmap.azurewebsites.net/" class="btn btn-outline-dark">Back to home</a></div> </div> <div id='maplegend' class='maplegend' style='position: absolute; z-index:9999; border:1px solid grey; background-color:rgba(255, 255, 255, 0.8); border-radius:6px; padding: 10px; font-size:15px; right: 11px; top: 150px;'> <div class='legend-title'>Activity type</div> <div class='legend-scale'> <ul class='legend-labels'> <li><span style='background:#ff9933;opacity:0.7;'></span>Run</li> <li><span style='background:#f6ff00;opacity:0.7;'></span>Ice Skate</li> <li><span style='background:#00ff55;opacity:0.7;'></span>Canoe</li> <li><span style='background:#00ffff;opacity:0.7;'></span>Nordic Ski</li> <li><span style='background:#00ccff;opacity:0.7;'></span>Alpine Ski</li> <li><span style='background:#0066ff;opacity:0.7;'></span>Ride</li> <li><span style='background:#cc00ff;opacity:0.7;'></span>Other</li> </ul> </div> </div> </body> </html> <style type='text/css'> .maplegend .legend-title { text-align: left; margin-bottom: 5px; font-weight: bold; font-size: 90%; } .maplegend .legend-scale ul { margin: 0; margin-bottom: 5px; padding: 0; float: left; list-style: none; } .maplegend .legend-scale ul li { font-size: 80%; list-style: none; margin-left: 0; line-height: 18px; margin-bottom: 2px; } .maplegend ul.legend-labels li span { display: block; float: left; height: 16px; width: 30px; margin-right: 5px; margin-left: 0; border: 1px solid #999; } .maplegend .legend-source { font-size: 80%; color: #777; clear: both; } .maplegend a { color: #777; } </style> {% endmacro %}""" macro = MacroElement() macro._template = Template(template) m.get_root().add_child(macro) return m