简体   繁体   中英

How do I add a secondary legend that explains what symbols mean with plotly express?

I have a plot which uses US states to map symbols. I currently assign symbols using the "state" column in my dataframe so that I can select particular states of interest by clicking or double clicking on the Plotly Express legend. This part is working fine. However, the symbol mapping I'm using also communicates information about territory, eg triangle-down means poor coverage in that state and many states will share this symbol. I would like to add another legend that shows what each shape means. How can I do this in Plotly Express? Alternatively, is there a way to display symbols in a footnote? I could also give the symbol definitions there.

The goal is to display that circle=Medium coverage, triangle-down=poor coverage, etc. in addition to the individual state legend I already have. If the legend is clickable such that I can select entire groups based on the symbol shape that would be the best possible outcome.

Thank you for any tips!

I tried using html and footnotes to display the symbols but it did not work.

在此处输入图像描述

  • as noted in comment, it can be achieved by additional traces on different axes
  • have simulated some data that matches what is implied in image and comments
  • from scatter figure extract out how symbols and colors have been assigned to states
  • build another scatter that is effectively a legend.
import pandas as pd
import numpy as np
import plotly.express as px

df_s = pd.read_html(
    "https://en.wikipedia.org/wiki/List_of_states_and_territories_of_the_United_States"
)[1].iloc[:, 0:2]

df_s.columns = ["name", "state"]

# generate a dataframe that matches structure in image and question
df = pd.DataFrame(
    {"activity_month": pd.date_range("1-jan-2020", "today", freq="W")}
).assign(
    value=lambda d: np.random.uniform(0, 1, len(d)),
    state=lambda d: np.random.choice(df_s["state"], len(d)),
)

# straight forward scatter
fig = px.scatter(df, x="activity_month", y="value", symbol="state", color="state")

# extract out how symbols and colors have been assigned to states
df_symbol = pd.DataFrame(
    [
        {"symbol": t.marker.symbol, "state": t.name, "color": t.marker.color}
        for t in fig.data
    ]
).assign(y=lambda d: d.index//20, x=lambda d: d.index%20)

# build a figure that effectively the legend
fig_legend = px.scatter(
    df_symbol,
    x="x",
    y="y",
    symbol="symbol",
    color="state",
    text="state",
    color_discrete_sequence=df_symbol["color"]
).update_traces(textposition="middle right", showlegend=False, xaxis="x2", yaxis="y2")

# insert legend into scatter and format axes
fig.add_traces(fig_legend.data).update_layout(
    yaxis_domain=[.15, 1],
    yaxis2={"domain": [0, .15], "matches": None, "visible": False},
    xaxis2={"visible":False},
    xaxis={"position":0, "anchor":"free"},
    showlegend=False
)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM