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 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")