def __init__( self, data=None, names=None, read_only=False, api_key=None, style=None, config_file=None, output_map=None, ): if api_key is not None: self.MAPBOX_API_KEY = api_key else: self.MAPBOX_API_KEY = os.getenv("MAPBOX_API_KEY") msg = "Warning: api_key not provided and MAPBOX_API_KEY " msg += "environment variable not set.\nMap may not display." if self.MAPBOX_API_KEY is None: print(msg) if config_file is None: self.config_file = resource_filename("rasta", "keplergl_config.json") else: self.config_file = config_file print(self.config_file) if output_map is not None: self.path = output_map + "_vis.html" else: self.path = os.path.join(tempfile.mkdtemp(), "defaultmap_vis.html") config = self.config(style=style) self.map = KeplerGl(config=config) if data is not None: self.add_data(data=data, names=names) self.html_path = self.render(read_only=read_only)
def plot_kepler(layers, names, config=None): """ Produces a kepler plot with data specified in layers. Arguments --------- layers (list): a list of geodataframes to add as kepler data in order of top to bottom layers. names (list) : a list of strings specifyig names of data layers in kepler. config (dict) : A kepler config dictionary. Returns ------- keplergl.keplergl.KeplerGl A kepler plot with data layers. Examples -------- TODO """ # intialize a base kepler plot plot = KeplerGl(height=500) index = 0 for layer in layers: # add data layer to kepler plot plot.add_data(data=layer, name=names[index]) # increment index index += 1 # check if a config is provided if config != None: plot.config = config return plot
def __init__(self, data=None, names=None, read_only=False, api_key=None, style=None): """Visualize data using kepler.gl Args: data Optional[Union[List[]]]: either None, a List of data objects, or a single data object. If data is not None, then Visualize(data) will perform all steps, including rendering and opening a browser. """ super(Visualize, self).__init__() if api_key is not None: self.MAPBOX_API_KEY = api_key else: self.MAPBOX_API_KEY = os.getenv('MAPBOX_API_KEY') msg = 'Warning: api_key not provided and MAPBOX_API_KEY ' msg += 'environment variable not set.\nMap may not display.' if self.MAPBOX_API_KEY is None: print(msg) config = self.config(style=style) self.map = KeplerGl(config=config) if data is not None: self.add_data(data=data, names=names) self.html_path = self.render(read_only=read_only)
def create_map_for_user(dict_m): """ Creates the map for a single user or several users in the db. Parameters ---------- dict_m : dictionary Dictionary containing the users gps data Returns ---------- keplergl map A map object containing all users points in the map. Can be printed with print(map) or saved to file via map.save_to_html(file_name=your_file_name) """ try: from keplergl import KeplerGl map_to_print = KeplerGl() for user in dict_m: df_map = dict_m[user] df_pp = pd.DataFrame(df_map, columns=["latitude", "longitude"]) map_to_print.add_data(data=df_pp, name=user) return map_to_print except: print("Kepler is not instaled!") print( "Please install kepler if you wish to generate map visualizations." )
def update_html(val): config_arcs = get_arcs_config(val) KeplerGl().save_to_html(file_name='templates/geoIF_arcs_centroids.html', data={'geodt': df_arcs_centroids}, config=config_arcs, read_only=True) return open('templates/geoIF_arcs_centroids.html', 'r').read()
def update_html_routes(val): config_routes = get_routes_config(val) KeplerGl().save_to_html(file_name='templates/geoIF_routes.html', data={'geodt': dg2}, config=config_routes, read_only=True) return open('templates/geoIF_routes.html', 'r').read()
def test(): "Test." from keplergl import KeplerGl height = 500 m = KeplerGl(height=height) assert m.height == height
def __init__(self, data=None, names=None, read_only=False, api_key=None, style=None, config_file=None, output_map=None): """Visualize data using kepler.gl Args: data Optional[Union[List[]]]: either None, a List of data objects, or a single data object. If data is not None, then Visualize(data) will perform all steps, including rendering and opening a browser. `config_file` provides the path of config file. 'output_map` provides the location html file, if none then will be dumped to temporaty files. """ super(Visualize, self).__init__() if api_key is not None: self.MAPBOX_API_KEY = api_key else: self.MAPBOX_API_KEY = os.getenv('MAPBOX_API_KEY') msg = 'Warning: api_key not provided and MAPBOX_API_KEY ' msg += 'environment variable not set.\nMap may not display.' if self.MAPBOX_API_KEY is None: print(msg) if config_file is None: self.config_file = resource_filename('keplergl_cli', 'keplergl_config.json') else: self.config_file = config_file if output_map is not None: self.path = output_map + '_vis.html' else: self.path = os.path.join(tempfile.mkdtemp(), 'defaultmap_vis.html') config = self.config(style=style) self.map = KeplerGl(config=config) if data is not None: self.add_data(data=data, names=names) self.html_path = self.render(read_only=read_only)
def main(): column_short = sys.argv[1] column_long = sys.argv[2] config_file = "keplergl_config.json" data_id = "buildings" config = read_configuration(config_file, label="Buildings", data_id=data_id, color_column=column_long) print("Using configuration (JSON syntax):") print(json.dumps(config, indent=2)) kepler = KeplerGl(config=config) kepler.add_data(data=open("buildings.geojson").read(), name=data_id) output = f"keplergl_{column_short}.html" kepler.save_to_html(file_name=output) name = column_long.replace("_", " ") # Add map title and creator with InPlace(output) as file: for line in file: line = line.replace( "<title>Kepler.gl</title>", f"<title>{name} – Campus Research Reopening Map" " by NCSU CGA</title>", ) line = line.replace("Kepler.gl Jupyter", "Kepler.gl Map by NCSU CGA") file.write(line)
def write_html(geojson_file, data_id, output_html, config, title): """Write Kepler.gl HTML and update its content""" # Lazy load non-standard dependencies to play nicely in cases # when only interface description is requested and the module # actually does not run. try: # pylint: disable=import-outside-toplevel from keplergl import KeplerGl from in_place import InPlace except ImportError as error: gs.fatal( _("Missing mandatory keplergl or in_place dependencies: {error}"). format(error=error)) # Useful to examine the resulting configuration # print("Using configuration (JSON syntax):") # print(json.dumps(config, indent=2)) kepler = KeplerGl(config=config) kepler.add_data(data=open(geojson_file).read(), name=data_id) kepler.save_to_html(file_name=output_html) # Add map title and creator with InPlace(output_html) as file: for line in file: line = line.replace( "<title>Kepler.gl</title>", f"<title>{title} – GRASS GIS Kepler.gl</title>", ) line = line.replace("Kepler.gl Jupyter", title) file.write(line)
def make_map(network): run_vehicle_position, queue_vehicle_position, closed_link_position = extract_vehicle_locations(network) # make gdf queue_vehicle_position_gdf = make_gdf(queue_vehicle_position) run_vehicle_position_gdf = make_gdf(run_vehicle_position) closed_link_gdf = add_closed_links(closed_link_position) # make map with open('keplergl_config.json') as jsonfile: map_config = json.load(jsonfile) map_vehicles = KeplerGl(height=400, config=map_config) # map_vehicles = KeplerGl(height=400) map_vehicles.add_data(data=queue_vehicle_position_gdf, name='queue vehicles') map_vehicles.add_data(data=run_vehicle_position_gdf, name='run vehicles') map_vehicles.add_data(data=closed_link_gdf, name='closed_links') return map_vehicles
def showTrajectoriesFromZones(origin_id, dest_id, direct): int_shapefile = gpd.read_file(direct + "TAZ/InternalCentroidZones.shp") # change ./.... to rootdir for DB ext_shapefile = gpd.read_file(direct + "TAZ/ExternalCentroidZones.shp") # change ./.... to rootdir for DB df = pd.read_csv("trajectories_condensed.csv") gdf_origins = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df['Origin X'], df['Origin Y'])) df = pd.read_csv("trajectories_condensed.csv") gdf_dests = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df['Dest X'], df['Dest Y'])) int_trajectories_origins = clusterByZone(gdf_origins, int_shapefile, merge=False) int_trajectories_dests = clusterByZone(gdf_dests, int_shapefile, merge=False) matching_trajectories = trajectoriesFromZones(int_trajectories_origins, int_trajectories_dests, origin_id, dest_id) df = pd.read_csv("trajectories_condensed.csv") chosen_zones_map = KeplerGl(height=500) int_zones = clusterByZone(gdf_origins, int_shapefile, merge=True) chosen_zones_map.add_data(data=df, name='Trajectories') chosen_zones_map.add_data(data=matching_trajectories, name='Matching Trajectories') chosen_zones_map.add_data(data=int_zones, name='Internal Zones') chosen_zones_map.save_to_html(file_name="chosen_zones_map.html") return chosen_zones_map
def geojson(gdf, height=400, name="layer", **kwargs): """ Convert Geodataframe to geojson and plot it. Parameters ---------- gdf : GeoDataframe height : Height of the plot. default: 400 name : name of the layer. default: 'layer' tooltip: tooltips shown in the map. eg: ['continent', 'pop_est'], color: color of the rendered geometries eg: [255,0,0], opacity: opacity of the rendered geometries eg: 0.1, stroke_color: stroke color of the rendered geometries eg: [0,0,0], stroke_thickness: stroke thickness of the rendered geometries eg: 1, color_field: field to base the color on eg: 'pop_est', color_scheme: color scheme for the geometries colored based on color_field eg: 'Blues', list of available color schemes: https://gist.github.com/jsundram/6004447#file-colorbrewer-json color_scheme_steps: Steps available in color schemes eg: 3-9,10,11,12 Returns ------- map : keplergl.keplergl.KeplerGl """ config_path = os.path.join(module_path, "config", "geojson.config") # Set Default Layername and Height kwargs.update({"height": height, "name": name}) if "color_field" in kwargs: col_type = str(gdf[kwargs["color_field"]].dtype) kwargs.update({"color_field_type": field_types[col_type]}) if "color_scheme" in kwargs: colorbrewer_path = os.path.join(module_path, "config", "colors.json") with open(colorbrewer_path) as f: colorbrewer = json.load(f) color_scheme = kwargs["color_scheme"] steps = kwargs.setdefault("color_scheme_steps", 6) colors = colorbrewer[color_scheme][str(steps)] kwargs.update({"colorbrewer": colors}) with open(config_path, "r") as f: t = Template(f.read()) config = ast.literal_eval(t.render(kwargs, id_=random_char(6))) map_ = KeplerGl(height=height, data={name: gdf}, config=config) return map_
# In[12]: import bokeh hv.save(baum_map, 'frankfurter_baum.html', backend='bokeh') # In[24]: # In[13]: from keplergl import KeplerGl import pandas as pd import geopandas as gpd # In[22]: map = KeplerGl(height=800) map.add_data(data=df, name="test") # mape = KeplerGl(height=500) # # In[23]: map # In[25]: config = map.config # In[29]:
class Visualize: """Quickly visualize data in browser over Mapbox tiles with the help of the AMAZING kepler.gl. """ def __init__(self, data=None, names=None, read_only=False, api_key=None, style=None): """Visualize data using kepler.gl Args: data Optional[Union[List[]]]: either None, a List of data objects, or a single data object. If data is not None, then Visualize(data) will perform all steps, including rendering and opening a browser. """ super(Visualize, self).__init__() if api_key is not None: self.MAPBOX_API_KEY = api_key else: self.MAPBOX_API_KEY = os.getenv('MAPBOX_API_KEY') msg = 'Warning: api_key not provided and MAPBOX_API_KEY ' msg += 'environment variable not set.\nMap may not display.' if self.MAPBOX_API_KEY is None: print(msg) config = self.config(style=style) self.map = KeplerGl(config=config) if data is not None: self.add_data(data=data, names=names) self.html_path = self.render(read_only=read_only) def config(self, style=None): """Load kepler.gl config and insert Mapbox API Key""" config_file = resource_filename('keplergl_cli', 'keplergl_config.json') # First load config file as string, replace {MAPBOX_API_KEY} with the # actual api key, then parse as JSON with open(config_file) as f: text = f.read() text = text.replace('{MAPBOX_API_KEY}', self.MAPBOX_API_KEY) keplergl_config = json.loads(text) # If style_url is not None, replace existing value standard_styles = [ 'streets', 'outdoors', 'light', 'dark', 'satellite', 'satellite-streets', ] if style is not None: style = style.lower() if style in standard_styles: # Just change the name of the mapStyle.StyleType key keplergl_config['config']['config']['mapStyle'][ 'styleType'] = style else: # Add a new style with that url d = { 'accessToken': self.MAPBOX_API_KEY, 'custom': True, 'id': 'custom', 'label': 'Custom map style', 'url': style } keplergl_config['config']['config']['mapStyle']['mapStyles'][ 'custom'] = d keplergl_config['config']['config']['mapStyle'][ 'styleType'] = 'custom' # Remove map state in the hope that it'll auto-center based on data # keplergl_config['config']['config'].pop('mapState') return keplergl_config['config'] def add_data(self, data, names=None): """Add data to kepler map Data should be either GeoJSON or GeoDataFrame. Kepler isn't aware of the geojson or shapely package, so if I supply an object from one of these libraries, first convert it to a GeoJSON dict. """ # Make `data` iterable if not isinstance(data, list): data = [data] # Make `names` iterable and of the same length as `data` if isinstance(names, list): # Already iterable, make sure they're the same length msg = 'data and names are iterables of different length' assert len(data) == len(names), msg else: # `names` not iterable, make sure it's the same length as `data` name_stub = 'data' if names is None else names names = [f'{name_stub}_{x}' for x in range(len(data))] for datum, name in zip(data, names): if any(isinstance(datum, c) for c in SHAPELY_GEOJSON_CLASSES): datum = dict(mapping(datum)) self.map.add_data(data=datum, name=name) def render(self, open_browser=True, read_only=False): """Export kepler.gl map to HTML file and open in Chrome """ # Generate path to a temporary file path = os.path.join(tempfile.mkdtemp(), 'vis.html') self.map.save_to_html(file_name=path, read_only=read_only) # Open saved HTML file in new tab in default browser webbrowser.open_new_tab('file://' + path) return path
coordinates = np.array( [tuple(crd.split(',')) for crd in airport_df.coordinates.tolist()]) airport_df['latitude'] = list(map(float, coordinates[:, 0])) airport_df['longitude'] = list(map(float, coordinates[:, 1])) airport_df.drop(labels='coordinates', axis='columns', inplace=True) airport_df.dropna(axis='index', subset=['iata'], inplace=True) airport_df.reset_index(drop=True, inplace=True) airport_df # + colab={"base_uri": "https://localhost:8080/", "height": 0} colab_type="code" executionInfo={"elapsed": 32918, "status": "ok", "timestamp": 1574653714933, "user": {"displayName": "So Negishi", "photoUrl": "", "userId": "14957100293746809516"}, "user_tz": 300} id="APOoXNf75-LT" outputId="dbb1fcc1-b527-482f-df8b-e43e5617b812" airport_df[airport_df.iata == 'JFK'] # + colab={"base_uri": "https://localhost:8080/", "height": 0} colab_type="code" executionInfo={"elapsed": 32915, "status": "ok", "timestamp": 1574653714934, "user": {"displayName": "So Negishi", "photoUrl": "", "userId": "14957100293746809516"}, "user_tz": 300} id="tS9Pv_2K5-LV" outputId="35d38b54-d0b7-4ec0-8e82-56b8bb1df5a0" airport_map = KeplerGl(height=900, width=800) airport_map_data = airport_df[[ 'name', 'latitude', 'longitude', 'facility_type' ]] airport_map.add_data( data=airport_map_data[airport_map_data.facility_type == 'large_airport'], name='large_airports') airport_map.add_data( data=airport_map_data[airport_map_data.facility_type == 'medium_airport'], name='medium_airports') airport_map.add_data( data=airport_map_data[airport_map_data.facility_type == 'small_airport'], name='small_airports') airport_map.save_to_html(file_name='./visualization/airport_map.html') # airport_map
from datetime import datetime from keplergl import KeplerGl import ast with open("df_freq.pkl", "rb") as f: df = pickle.load(f) df = df[["Latitude", "Longitude", "Ryear", "Cluster_ID", "Topic_ID", "freq_words"]] df["Timestamp"] = df["Ryear"].apply(lambda x: datetime.timestamp(datetime(year=x, month=1, day=1))) df = df.drop_duplicates() cluster_topic_data = {} clusters = np.unique(df["Cluster_ID"]) for cluster in clusters: df2 = df.loc[df["Cluster_ID"] == cluster] topicids = np.unique(df2["Topic_ID"]) cluster_topic_data[cluster] = {} for topicid in topicids: s = f"topic_{topicid}" df3 = df2.loc[df2["Topic_ID"] == topicid] cluster_topic_data[cluster][s] = df3 for cluster in clusters: with open('./config/config_'+str(cluster)+'.txt', "r") as f: config = f.read() x = ast.literal_eval(config) w = KeplerGl(data=cluster_topic_data[cluster], config=x) file_name = f"./kepler/map_{cluster}.html" w.save_to_html(file_name=file_name)
from keplergl import KeplerGl # df needs to contain 'latitude' and 'longitude' columns map_ = KeplerGl(height=700) map_.add_data(df, 'Data') map_.save_to_html(file_name='try.html')
def generate_map(query_results: List[QueryResult], height: int = 500, config: Optional[Dict] = KEPLER_DEFAULT_CONFIG, column: Optional[Union[str, List[str]]] = None, weights: Optional[List[int]] = None, clusters: Optional[Union[bool, float]] = False) -> KeplerGl: """ Returns Kepler map combining multiple query results. :param query_results: List of QueryResult objects :param height: Height of the map :param config: Kepler config dict to use for styling the map. :param column: Name of the field or JSON column in each QueryResult to plot. Note that if you have calculated some statistics of a JSON field in QueryResult, the dataframe is flattened already, and you must use only the name of the field inside the JSON. You may provide a list of names (same length as query_results) if you wish to plot different columns in different dataframes. :param weights: Optional. If present, will also calculate a weighted sum of any H3 datasets. Must have the same length as query_results. If a dataset has no hex column, it will not be included. :param clusters: If True, will also calculate spatial clusters and outliers for the weighted sum. You may specify the statistical significance threshold by specifying a float instead. The default threshold is 0.05. If weights is not present, does nothing. """ config = deepcopy(config) center = QueryResult.get_center_of_all(query_results) zoom = QueryResult.get_zoom_of_all(query_results) has_strings = list( filter(lambda qr: qr.geom_type in ['MultiLineString', 'LineString'], query_results)) if center: config['config']['mapState'].update(**center) if zoom: config['config']['mapState']['zoom'] = zoom if has_strings: config['config']['visState']['layerBlending'] = 'additive' map_1 = KeplerGl(height=height) # empty the layer config, add point or hex layer, depending on presence of hex column config["config"]["visState"]["layers"] = [] for i, qr in enumerate(query_results, start=1): if not qr.is_empty: name = qr.name if qr.name is not None else f'data_{i}' map_1.add_data(data=qr.gdf, name=name) hex_column = next( (col for col in qr.gdf.columns if col.startswith("hex")), False) if hex_column: # add hex layer hex_layer_config = deepcopy(KEPLER_DEFAULT_HEX_LAYER_CONFIG) hex_layer_config["id"] = f"{hex_column}_{name}" hex_layer_config["config"]["dataId"] = name hex_layer_config["config"]["label"] = f"{hex_column}_{name}" hex_layer_config["config"]["columns"]["hex_id"] = hex_column # Also column that the user wishes to plot may change if column: # Allow plotting different columns for different queries, or same column for all data_column = column if isinstance(column, str) else column[i - 1] hex_layer_config["visualChannels"]["colorField"][ "name"] = data_column if qr.gdf[data_column].dtype == "float64": hex_layer_config["visualChannels"]["colorField"][ "type"] = "real" elif qr.gdf[data_column].dtype == "int64": hex_layer_config["visualChannels"]["colorField"][ "type"] = "integer" config["config"]["visState"]["layers"].append(hex_layer_config) else: # add point layer for raw data layer_config = deepcopy(KEPLER_DEFAULT_LAYER_CONFIG) layer_config["id"] = name layer_config["config"]["dataId"] = name layer_config["config"]["label"] = name config["config"]["visState"]["layers"].append(layer_config) # Generate a new queryresult summing the hex layers if weights are present if weights: if isinstance(column, str): column = [column] * len(weights) sum_layer = generate_sum_layer(query_results, column, weights) name = sum_layer.name map_1.add_data(data=sum_layer.gdf, name=name) hex_column = next( (col for col in sum_layer.gdf.columns if col.startswith("hex")), False) # Hide the individual layers if sum is displayed for layer_config in config["config"]["visState"]["layers"]: layer_config["config"]["isVisible"] = False # add hex layer hex_layer_config = deepcopy(KEPLER_DEFAULT_HEX_LAYER_CONFIG) hex_layer_config["id"] = name hex_layer_config["config"]["dataId"] = name hex_layer_config["config"]["label"] = name hex_layer_config["config"]["columns"]["hex_id"] = hex_column hex_layer_config["visualChannels"]["colorField"]["name"] = name hex_layer_config["visualChannels"]["colorField"]["type"] = "real" config["config"]["visState"]["layers"].append(hex_layer_config) if clusters: if isinstance(clusters, float): cluster_gdf = generate_clusters(gdf=sum_layer.gdf, col="sum", alpha=clusters) else: cluster_gdf = generate_clusters(gdf=sum_layer.gdf, col="sum") name = 'clusters' map_1.add_data(data=cluster_gdf, name=name) hex_column = next( (col for col in cluster_gdf.columns if col.startswith("hex")), False) # add cluster layer cluster_layer_config = deepcopy( KEPLER_DEFAULT_CLUSTER_LAYER_CONFIG) cluster_layer_config["id"] = name cluster_layer_config["config"]["dataId"] = name cluster_layer_config["config"]["label"] = name cluster_layer_config["config"]["columns"]["hex_id"] = hex_column cluster_layer_config["config"]["isVisible"] = False config["config"]["visState"]["layers"].append(cluster_layer_config) # filter cluster layer so that only statistically significant clusters # are displayed by default config["config"]["visState"]["filters"].append( KEPLER_DEFAULT_CLUSTER_FILTER_CONFIG) map_1.config = config return map_1
def generate_vis(): config = { "version": "v1", "config": { "visState": { "filters": [], "layers": [ { "id": "rfnq31gn", "type": "grid", "config": { "dataId": "income", "label": "Point", "color": [ 255, 203, 153 ], "columns": { "lat": "Lat", "lng": "Lon" }, "isVisible": True, "visConfig": { "opacity": 0.89, "worldUnitSize": 15, "colorRange": { "name": "Global Warming", "type": "sequential", "category": "Uber", "colors": [ "#5A1846", "#900C3F", "#C70039", "#E3611C", "#F1920E", "#FFC300" ] }, "coverage": 1, "sizeRange": [ 0, 1000 ], "percentile": [ 0, 100 ], "elevationPercentile": [ 0, 100 ], "elevationScale": 5, "colorAggregation": "average", "sizeAggregation": "average", "enable3d": True }, "hidden": False, "textLabel": [ { "field": None, "color": [ 255, 255, 255 ], "size": 18, "offset": [ 0, 0 ], "anchor": "start", "alignment": "center" } ] }, "visualChannels": { "colorField": { "name": "Median", "type": "integer" }, "colorScale": "quantile", "sizeField": { "name": "Median", "type": "integer" }, "sizeScale": "linear" } } ], "interactionConfig": { "tooltip": { "fieldsToShow": { "97ap1ofch": [ { "name": "id", "format": None }, { "name": "State_Code", "format": None }, { "name": "State_Name", "format": None }, { "name": "State_ab", "format": None }, { "name": "County", "format": None } ] }, "compareMode": False, "compareType": "absolute", "enabled": True }, "brush": { "size": 0.5, "enabled": False }, "geocoder": { "enabled": False }, "coordinate": { "enabled": False } }, "layerBlending": "normal", "splitMaps": [], "animationConfig": { "currentTime": None, "speed": 1 } }, "mapState": { "bearing": 24, "dragRotate": True, "latitude": 30.067203168518454, "longitude": -128.1037388392268, "pitch": 50, "zoom": 3.379836309981588, "isSplit": False }, "mapStyle": { "styleType": "dark", "topLayerGroups": {}, "visibleLayerGroups": { "label": True, "road": True, "border": False, "building": True, "water": True, "land": True, "3d building": False }, "threeDBuildingColor": [ 9.665468314072013, 17.18305478057247, 31.1442867897876 ], "mapStyles": {} } } } m = KeplerGl() m.config = config m.add_data(data=import_data(), name="income") m.save_to_html(file_name="index.html")
import geopandas as gpd # ========================= Data Prep ========================= # Pre-processed shapefile data and corresponding state information combined merged_dict = pd.read_csv('nws_shapefile_translated.csv') # data courtesy of https://mappingpoliceviolence.org/ mvp_raw = pd.read_csv("2013-2019 Police Killings_june05.csv") mvp_raw = mvp_raw.rename(columns={'State':'STATE'}) # merge the recorded deaths dataset with the pre-processed shapefile data kepler_mvp_df = pd.merge(mvp_raw,merged_dict, on=['STATE','County']) kepler_mvp_df = kepler_mvp_df.dropna(subset=["Victim's name"]) kepler_mvp_df = kepler_mvp_df.rename(columns={'Date of Incident (month/day/year)':'datetime'}) kepler_mvp_df = kepler_mvp_df.sort_values(by="datetime") kepler_mvp_df[‘datetime’] = kepler_mvp_df[‘datetime’].astype(str) + ‘ 0:00’ # ========================= Map Generation ========================= from keplergl import KeplerGl mvp_map = KeplerGl(height=1000, data={'police actions that resulted in death': kepler_mvp_df}) # modify the map settings as you desire until you have your final map. # This saves our current map configuration as current_config current_config = mvp_map.config #Thats it! Kepler.gl makes it really easy to build complex detailed 3D maps.
"pk.eyJ1IjoianVzdHN0YW4iLCJhIjoiY2tlc3hncWJ4MWh3cTJ4cXY5ZmsxdmoyYiJ9.LHycdQ3Il_MDxeW8JfiNWw", "custom": True, "icon": "https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/static/-122.3391,37.7922,9,0,0/400x300?access_token=pk.eyJ1IjoianVzdHN0YW4iLCJhIjoiY2tlc3hncWJ4MWh3cTJ4cXY5ZmsxdmoyYiJ9.LHycdQ3Il_MDxeW8JfiNWw&logo=false&attribution=false", "id": "satellite-streets", "label": "Mapbox Satellite Streets", "url": "mapbox://styles/mapbox/satellite-streets-v11" } } } } } ## 1st df = pd.read_csv("data/olist_orders_geo.csv") map_1 = KeplerGl(height=600, width=800, data={"data_1": df}, config=config) map_1.add_data(data=df, name='data_1') map_1.data print(df.head()) gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.cust_lng, df.cust_lat)) viz = Visualize(gdf, api_key=MAPBOX_API_KEY) viz.render(open_browser=True, read_only=False) map_1.save_to_html(data={'data_1': df}, config=config, file_name='olist-order-geo-config.html')
def create_map(self, filename='airport_map'): flight_map = KeplerGl(height=500, width=800) flight_feature_collection = { 'type': 'FeatureCollection', 'features': self.flight_list } large_airport_feature_collection = { 'type': 'FeatureCollection', 'features': [ airport for airport in self.airport_list if airport['properties']['facility_type'] == 'large_airport' ] } medium_airport_feature_collection = { 'type': 'FeatureCollection', 'features': [ airport for airport in self.airport_list if airport['properties']['facility_type'] == 'medium_airport' ] } small_airport_feature_collection = { 'type': 'FeatureCollection', 'features': [ airport for airport in self.airport_list if airport['properties']['facility_type'] == 'small_airport' ] } flight_map.add_data(data=flight_feature_collection, name='flights') flight_map.add_data(data=large_airport_feature_collection, name='large_airports') flight_map.add_data(data=medium_airport_feature_collection, name='medium_airports') flight_map.add_data(data=small_airport_feature_collection, name='small_airports') flight_map.save_to_html(file_name=f'{filename}.html') return flight_map
import pandas as pd import os from six.moves import urllib import pandas as pd # importing the Pandas Library as 'pd' from keplergl import KeplerGl # importing KeplerGl import geopandas as gpd # importing geopandas as 'gpd' # datasheet dataset = pd.read_csv("poluition_map.csv", encoding='utf8', delimiter=',', engine='python') dataset.head() #Create a basemap map = KeplerGl(height=600, width=800) # Create a geodataframe gdf = gpd.GeoDataFrame(dataset, geometry=gpd.points_from_xy(dataset.latitude, dataset.longitude)) #make sure that your latitude and longitude are named as they are in your csv map.add_data(data=gdf, name="IQA") # add geoenabled dataframe to map map.save_to_html(file_name='GeoViz.html') map
"styleType": "dark", "topLayerGroups": {}, "visibleLayerGroups": { "label": True, "road": True, "border": False, "building": True, "water": True, "land": True, "3d building": False }, "threeDBuildingColor": [9.665468314072013, 17.18305478057247, 31.1442867897876], "mapStyles": {} } } } # COMMAND ---------- # DBTITLE 1,Plot Data from keplergl import KeplerGl m1 = KeplerGl(config=plot1_conf) m1.add_data(data=total_spend_pd[["id", "spend", "wkt"]], name="spend") displayKepler(m1, 1000) # COMMAND ----------
class RastaKepler(Visualize): """Inheriting from the `Visualize` and adding option to pass the output map to save map at custom location alongisde the option to pass a custom config file. """ def __init__( self, data=None, names=None, read_only=False, api_key=None, style=None, config_file=None, output_map=None, ): if api_key is not None: self.MAPBOX_API_KEY = api_key else: self.MAPBOX_API_KEY = os.getenv("MAPBOX_API_KEY") msg = "Warning: api_key not provided and MAPBOX_API_KEY " msg += "environment variable not set.\nMap may not display." if self.MAPBOX_API_KEY is None: print(msg) if config_file is None: self.config_file = resource_filename("rasta", "keplergl_config.json") else: self.config_file = config_file print(self.config_file) if output_map is not None: self.path = output_map + "_vis.html" else: self.path = os.path.join(tempfile.mkdtemp(), "defaultmap_vis.html") config = self.config(style=style) self.map = KeplerGl(config=config) if data is not None: self.add_data(data=data, names=names) self.html_path = self.render(read_only=read_only) def config(self, style=None): """Load kepler.gl config and insert Mapbox API Key""" # config_file = resource_filename('keplergl_cli', 'keplergl_config.json') # First load config file as string, replace {MAPBOX_API_KEY} with the # actual api key, then parse as JSON with open(self.config_file) as f: text = f.read() text = text.replace("{MAPBOX_API_KEY}", self.MAPBOX_API_KEY) keplergl_config = json.loads(text) # If style_url is not None, replace existing value standard_styles = [ "streets", "outdoors", "light", "dark", "satellite", "satellite-streets", ] if style is not None: style = style.lower() if style in standard_styles: # Just change the name of the mapStyle.StyleType key keplergl_config["config"]["config"]["mapStyle"][ "styleType"] = style else: # Add a new style with that url d = { "accessToken": self.MAPBOX_API_KEY, "custom": True, "id": "custom", "label": "Custom map style", "url": style, } keplergl_config["config"]["config"]["mapStyle"]["mapStyles"][ "custom"] = d keplergl_config["config"]["config"]["mapStyle"][ "styleType"] = "custom" # Remove map state in the hope that it'll auto-center based on data # keplergl_config['config']['config'].pop('mapState') return keplergl_config["config"] def render(self, open_browser=True, read_only=False): """Export kepler.gl map to HTML file and open in Chrome""" self.map.save_to_html(file_name=self.path, read_only=read_only) # Open saved HTML file in new tab in default browser if open_browser: webbrowser.open_new_tab("file://" + self.path) return self.path
import config import configparser import pandas as pd #importing the Pandas Library as 'pd' from keplergl_cli import Visualize #importing KeplerGl from keplergl import KeplerGl import geopandas as gpd #importing geopandas as 'gpd' #add mapbox API key MAPBOX_API_KEY = config.MAPBOX_API df = pd.read_csv("data/olist_orders_geo.csv") print(df.head()) map_1 = KeplerGl(height=600, width=800) map_1.add_data(data=df, name='data_1') map_1.data print(df.head()) gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.cust_lng, df.cust_lat)) viz = Visualize(gdf, api_key=MAPBOX_API_KEY) viz.render(open_browser=True, read_only=False) map_1.save_to_html(data={'data_1': df}, file_name='olist-order-geo.html')
from keplergl import KeplerGl map1 = KeplerGl(height=600) map1.add_data(data=df) map1
# Concatenate all districts into one dataframe output_district = gpd.GeoDataFrame(pd.concat(district_map, ignore_index=True)).reset_index()\ .rename(columns={'index': 'district'}) # Simplify geometry output_district['geometry'] = output_district['geometry'].simplify( tolerance=GEOM_SIMPLIFICATION) # Concatenate all provinces into one dataframe province_map = gpd.GeoDataFrame(pd.concat(province_map, ignore_index=True)) # Concatenate all provinces into one dataframe municipality_map = gpd.GeoDataFrame( pd.concat(municipality_map, ignore_index=True)) # Feature Engineer dataframe # Create maps KeplerGl(height=800, width=1000).save_to_html( { 'district': output_district, 'province': province_map, 'municipality': municipality_map }, file_name=base_path.joinpath( 'maps', f'districts-spain-simplification-{GEOM_SIMPLIFICATION}.html'), center_map=True) # Output districts to excel output_district = output_district.drop('geometry', axis=1) pd.DataFrame(output_district).to_excel('assembled_districts_spain.xlsm', index=False)
def plot_map_station_with_kepler(station_control, station_id=None): """ Affiche une cartographie de l'agglomération de Bordeaux avec toutes les stations Vcub et leurs états provenant des algorithmes (normal, inactive et anomaly). Si "station_id" est indiqué, alors la cartographie est focus sur la lat / lon de station (Numéro) Parameters ---------- data : pd.DataFrame En provenance de station_control.csv (vcub_watcher) station_id : Int [opt] Numéro de station que l'on souhaite voir (en focus) sur la cartographie. Returns ------- map_kepler : Graphique Examples -------- map_kepler = plot_map_station_with_kepler(data=station_control, station_id=6) """ # Global config plot config_global = { "version": "v1", "config": { "visState": { "filters": [], "layers": [ { "id": "fmdzqhw", "type": "point", "config": { "dataId": "data_1", "label": "Station Vcub", "color": [ 18, 147, 154 ], "columns": { "lat": "lat", "lng": "lon", "altitude": None }, "isVisible": True, "visConfig": { "radius": 12, "fixedRadius": False, "opacity": 0.8, "outline": False, "thickness": 2, "strokeColor": None, "colorRange": { "name": "Custom Palette", "type": "custom", "category": "Custom", "colors": [ "#696A6A", "#6DDE75", "#EB4D50", "#5E9BE6" ] }, "strokeColorRange": { "name": "Global Warming", "type": "sequential", "category": "Uber", "colors": [ "#5A1846", "#900C3F", "#C70039", "#E3611C", "#F1920E", "#FFC300" ] }, "radiusRange": [ 0, 50 ], "filled": True }, "hidden": False, "textLabel": [ { "field": None, "color": [ 255, 255, 255 ], "size": 18, "offset": [ 0, 0 ], "anchor": "start", "alignment": "center" } ] }, "visualChannels": { "colorField": { "name": "etat_id_sort", "type": "integer" }, "colorScale": "ordinal", "strokeColorField": None, "strokeColorScale": "quantile", "sizeField": None, "sizeScale": "linear" } } ], "interactionConfig": { "tooltip": { "fieldsToShow": { "data_1": [ { "name": "station_id", "format": None }, { "name": "NOM", "format": None }, { "name": "etat", "format": None }, { "name": "available_bikes", "format": None }, { "name": "anomaly_since_str", "format": None } ] }, "compareMode": True, "compareType": "absolute", "enabled": True }, "brush": { "size": 0.5, "enabled": False }, "geocoder": { "enabled": False }, "coordinate": { "enabled": False } }, "layerBlending": "normal", "splitMaps": [], "animationConfig": { "currentTime": None, "speed": 1 } }, "mapState": { "bearing": 0, "dragRotate": False, "latitude": 44.85169239146265, "longitude": -0.5868239240658858, "pitch": 0, "zoom": 11.452871077625481, "isSplit": False }, "mapStyle": { "styleType": "muted", "topLayerGroups": { "water": False }, "visibleLayerGroups": { "label": True, "road": True, "border": False, "building": True, "water": True, "land": True, "3d building": False }, "threeDBuildingColor": [ 137, 137, 137 ], "mapStyles": {} } } } # Preprocess avant graphique station_control['etat'] = 'normal' # Non monitoré station_control.loc[station_control['mean_activity'] < THRESHOLD_PROFILE_STATION, 'etat'] = 'non surveillée' # En anoamlie (HS prediction) station_control.loc[station_control['is_anomaly'] == 1, 'etat'] = 'anomaly' # Inactive station_control.loc[station_control['is_inactive'] == 1, 'etat'] = 'inactive' # Transform date to string try: station_control['anomaly_since_str'] = \ station_control['anomaly_since'].dt.strftime(date_format='%Y-%m-%d %H:%M') except KeyError: # Pour vcub_watcher intégration # https://github.com/armgilles/vcub_keeper/issues/49#issuecomment-822504771 station_control['anomaly_since_str'] = \ station_control['En anomalie depuis'].dt.strftime(date_format='%Y-%m-%d %H:%M') # Drop date for Kepler station_control = station_control.drop(['last_date_anomaly', 'anomaly_since'], axis=1) # Add fake stations to have every type of etat (anomaly / normal / inactive # & non surveillée) to match with fill color in plot fake_station_every_etat = \ [[990, 0.4, 1, 0, 35, 60.9616624, -39.1527227, 'Station fake anomaly', 'anomaly', '2021-04-07 09:00'], [991, 0.42, 1, 0, 21, 60.9616624, -39.1527227, 'Station fake normal', 'normal', '-'], [992, 0.36, 0, 1, 22, 60.9616624, -39.1527227, 'Station fake inactive', 'inactive', '-'], [993, 0.0, 0, 0, 22, 60.9616624, -39.1527227, 'Station non surveillée', 'non surveillée', '-']] fake_station_every_etat_df = pd.DataFrame(fake_station_every_etat, columns=station_control.columns) station_control = pd.concat([station_control, fake_station_every_etat_df]) # Sorting DataFrame to fill color in correct order etat_id_sort = {'non surveillée': 0, 'normal': 1, 'anomaly': 2, 'inactive': 3} station_control['etat_id_sort'] = station_control['etat'].map(etat_id_sort) station_control = station_control.sort_values('etat_id_sort') # Param plot with a given station_id if station_id is not None: # On centre le graphique sur la lat / lon de la station center_lat = \ station_control[station_control['station_id'] == station_id]['lat'].values[0] center_lon = \ station_control[station_control['station_id'] == station_id]['lon'].values[0] config_global['config']['mapState']['latitude'] = center_lat config_global['config']['mapState']['longitude'] = center_lon config_global['config']['mapState']['zoom'] = 15.3 config_global['config']['mapState']['bearing'] = 24 config_global['config']['mapState']['dragRotate'] = True config_global['config']['mapState']['pitch'] = 54 # Building 3D config_global['config']['mapStyle']['visibleLayerGroups']['3d building'] = True # file_name = 'keplergl_map_station.html' else: # file_name = 'keplergl_map_global.html' pass # Load kepler.gl with map data and config map_kepler = KeplerGl(height=400, data={"data_1": station_control}, config=config_global) # Export # map_kepler.save_to_html(file_name=file_name) # No more export return map_kepler