Come creare un simbolo di pulsante su un Plotly choropleth mappa

0

Domanda

Voglio creare pulsanti di un Plotly choropleth mappa come i pulsanti (che i miei tre frecce rosse indicano) sulla mappa https://resources-covid19canada.hub.arcgis.com/. Quando il pulsante di windows di legenda.

Il tuo suggerimento sarebbe molto apprezzato.

Grazie per il vostro aiuto!

button choropleth plotly
2021-11-22 22:01:35
1
0
  • è possibile ottenere il tipo di figura si mostra con plotly. Non ci sono più problemi con l'utilizzo di simboli su di mapbox trame. Quindi se si vuole il colore, la dimensione e l'uso di forme diverse, è necessario utilizzare geojson livelli
  • avere una leggenda in modo simile non è davvero possibile. Chiaramente hai file leggenda. Il dimensionamento e la forma dei marcatori è veramente basso per l'aspetto visivo senza una leggenda
  • il codice completo è alla fine
px.choropleth_mapbox(
    df.loc[df["SummaryDate"].eq(df["SummaryDate"].max())].merge(df_t, on="Abbreviation"),
    geojson=gdf_can.geometry,
    locations="Abbreviation",
    color="DailyTotals",
    hover_data={"Province":True, "SummaryDate":True, "Change":":.2%"},
    color_continuous_scale="BuPu"
).update_layout(
    mapbox={
        "style": "carto-positron",
        "zoom": 2,
        "center": {
            "lon": sum(gdf_can.total_bounds[[0, 2]]) / 2,
            "lat": sum(gdf_can.total_bounds[[1, 3]]) / 2,
        },
        "layers": px_marker_mapbox(
            df_t.join(gdf_can),
            color_discrete_map={
                "solid/arrow-up": "yellow",
                "solid/arrow-down": "silver",
            },
        ),
    },
    margin={"l": 0, "r": 0, "t": 0, "b": 0},
)

enter image description here

codice di installazione

import geopandas as gpd
import pandas as pd
import requests
import plotly.express as px
import shapely.geometry
import svgpath2mpl
import numpy as np

# create shapely multi-polygon from maki or font-awesome SVG path
def marker(name="star", source="fa"):
    def to_shapely(mpl, simplify=0):
        p = shapely.geometry.MultiPolygon(
            [shapely.geometry.Polygon(a).simplify(simplify) for a in mpl]
        )
        p = shapely.affinity.affine_transform(
            p,
            [1, 0, 0, -1, 0, 0],
        )
        scale = 1 if source == "maki" else 10 ** -2
        p = shapely.affinity.affine_transform(
            p,
            [1, 0, 0, 1, -p.centroid.x, -p.centroid.y],
        )
        return shapely.affinity.affine_transform(
            p,
            [scale, 0, 0, scale, -p.centroid.x, -p.centroid.y],
        )

    if source == "maki":
        url = f"https://raw.githubusercontent.com/mapbox/maki/main/icons/{name}.svg"
    elif source == "fa":
        url = f"https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/{name}.svg"
    svgpath = pd.read_xml(requests.get(url).text).loc[0, "d"]
    return to_shapely(svgpath2mpl.parse_path(svgpath).to_polygons())

# create mapbox layers for markers.  icon defines layer and color
def px_marker_mapbox(
    df,
    icon="icon",
    size="size",
    lat="lat",
    lon="lon",
    color_discrete_map=None,
    color_discrete_sequence=px.colors.qualitative.Plotly,
):
    layers = []
    for i, g in enumerate(df.groupby(icon)):
        m = marker(g[0])
        geoms = [
            shapely.affinity.affine_transform(
                m, [r[1][size], 0, 0, r[1][size], r[1][lon], r[1][lat]]
            )
            for r in g[1].iterrows()
        ]
        if color_discrete_map and g[0] in color_discrete_map.keys():
            color = color_discrete_map[g[0]]
        else:
            color = color_discrete_sequence[i % len(color_discrete_sequence)]
        layers.append(
            {
                "source": gpd.GeoSeries(geoms).__geo_interface__,
                "type": "fill",
                "color": color,
            }
        )

    return layers


# fmt: off
gdf_can = gpd.GeoDataFrame.from_features(requests.get("https://data.opendatasoft.com/explore/dataset/georef-canada-province@public/download/?format=geojson&timezone=Europe/London&lang=en").json())
gdf_can["lat"] = gdf_can["geo_point_2d"].apply(lambda l: l[0])
gdf_can["lon"] = gdf_can["geo_point_2d"].apply(lambda l: l[1])

# two different province codes used by COVID and geometry, get map...
df_prov = pd.read_html("https://www150.statcan.gc.ca/n1/pub/92-195-x/2011001/geo/prov/tbl/tbl8-eng.htm")[0].drop(13)
df_prov = df_prov.rename(
    columns={
        "Internationally approved alpha code (Source: Canada Post)": "Abbreviation",
        "Standard geographical classification (SGC) code": "prov_code",
    }
)

gdf_can = gdf_can.merge(df_prov.loc[:, ["prov_code", "Abbreviation"]], on="prov_code").set_index("Abbreviation")

# get COVID daily data...
df = pd.json_normalize(requests.get("https://opendata.arcgis.com/datasets/3afa9ce11b8842cb889714611e6f3076_0.geojson").json()["features"])
df = df.rename(columns={c:c.split(".")[1] for c in df.columns if len(c.split("."))==2})
df["SummaryDate"] = pd.to_datetime(df["SummaryDate"].str[0:10]) if df["SummaryDate"].dtype=="O" else df["SummaryDate"]
df = df.loc[df["SummaryDate"].ge(df["SummaryDate"].max()-pd.Timedelta(days=7)) & df["Abbreviation"].ne("CA")]
# fmt: on

# rollup changes data...
df_t = df.groupby("Abbreviation")["DailyTotals"].apply(
    lambda s: s.pct_change(periods=7).dropna()
).to_frame().rename(columns={"DailyTotals":"Change"}).assign(
    icon=lambda d: np.select(
        [d["Change"] < -0.1, d["Change"] > 0.1],
        ["solid/arrow-down", "solid/arrow-up"],
        "solid/arrows-alt-h",
    ),
    size=lambda d: d["Change"].abs()
).droplevel(1)
2021-11-23 20:11:04

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................