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
Exemple #2
0
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
Exemple #3
0
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")