Marginal_y/x hover data in px.scatter broken when used with hovertemplate

Hi All,
The hover data on the right gray box plot is broken when the scatter plot code includes certain aspects of hovertemplate.

fig.update_traces(hovertemplate=.....)

Here’s the data and the code to replicate:

import pandas as pd     #(version 1.0.0)
import plotly           #(version 4.5.4)
import plotly.express as px
import plotly.io as pio

df = pd.read_csv("final_covid.csv")
df.dropna(subset=['women'], inplace=True)
df['total_employed'] = pd.to_numeric(df['total_employed'])
df['total_employed'] = df['total_employed']*1000

fig = px.scatter(
    data_frame=df,
    x="proximity",
    y="exposure",
    size="total_employed",
    color="Majority Employed",
    opacity=0.8,
    color_discrete_map={"Women":"blue","Men":"gray"},
    custom_data=['occupation'],

    marginal_x='box',
    marginal_y='box',

    title='Workers at Highest Risk of Coronavirus',
    template='ggplot2',
)

fig.update_traces(hovertemplate=
        "<b>%{customdata}</b><br><br>" +
        "Exposure: %{y}<br>" +
        "Proximity: %{x}<br>" +
        "Total Employed: %{marker.size:,}" +
        "<extra></extra>",
)

fig.update_layout(legend=dict(x=.8, y=1))
pio.show(fig)

As you can see, %{y} and %{x} work fine, but not %{customdata} or %{marker.size:,}.

Maybe we can fix this in the next update.

Thank you,
Adam

Hi @adamschroeder, this is not really a bug here, because what you should do here is to pass the columns to the hover_data argument of px.scatter, and then the columns are passed to traces in the marginals too. If you do this you will have all the information in the hover of the different subplots. without the need to change the hovertemplate. If you wish to customize the hovertemplate of course you can as in the code below; I’ve used the selector attribute of fig.update_traces in order to select a different hovertemplate for the scatter and box plots (if you had outliers in the marginal_x you would need to use a different selector, such as the xaxis and yaxis)

import pandas as pd     #(version 1.0.0)
import plotly           #(version 4.5.4)
import plotly.express as px
import plotly.io as pio

df = pd.read_csv("~/Downloads/final_covid.csv")
df.dropna(subset=['women'], inplace=True)
df['total_employed'] = pd.to_numeric(df['total_employed'])
df['total_employed'] = df['total_employed']*1000

fig = px.scatter(
    data_frame=df,
    x="proximity",
    y="exposure",
    size="total_employed",
    color="Majority Employed",
    opacity=0.8,
    color_discrete_map={"Women":"blue","Men":"gray"},
    hover_data=['occupation', 'total_employed'],

    marginal_x='box',
    marginal_y='box',

    title='Workers at Highest Risk of Coronavirus',
    template='ggplot2',
)

fig.update_traces(hovertemplate=
        "<b>%{customdata[0]}</b><br><br>" +
        "Exposure: %{y}<br>" +
        "Proximity: %{x}<br>" +
        "Total Employed: %{customdata[1]}" +
        "<extra></extra>",
                  selector={'type':'scatter'}
)
fig.update_traces(hovertemplate=
        "<b>%{customdata[0]}</b><br><br>" +
        "Exposure: %{y}<br>" +
        "Total Employed: %{customdata[1]}" +
        "<extra></extra>",
                  selector={'type':'box'}
)

fig.update_layout(legend=dict(x=.8, y=1))
fig.show()

Of course feel free to suggest improvements to the documentation if you think additional examples or explanations could help.

Hi @Emmanuelle,
thank you for the clarification. My mistake was to use custom_data within the px.scatter(). Using hover_data makes it work. I used your code (copy-paste) and it works great.

However, when I add the rug plot to the marginal x instead of the original box plot I had there before:

marginal_x='rug',

And I add the following trace to your code

scatterplot.update_traces(hovertemplate=
        "<b>%{customdata[0]}</b><br><br>" +
        "Proximity: %{x}<br>" +
        "Total Employed: %{customdata[1]:,}" +
        "<extra></extra>",
        selector={'type':'rug'}
)

I get an error, in the hover, where the Exposure=men or women instead of the xaxis proximity value.

Do you know why that is?

It’s because the rug plot is made with a box trace so the selector which you are using is not used for the rug plot and instead the one of the box plot is used. (You can do a print(fig) to check the content of the px-generated figure).
You should instead select according to the axis like

fig.update_traces(hovertemplate=
        "<b>%{customdata[0]}</b><br><br>" +
        "Proximity: %{x}<br>" +
        "Total Employed: %{customdata[1]:,}" +
        "<extra></extra>",
        selector={'xaxis':'x3', 'yaxis':'y3'}
)

That’s what you meant with the xaxis and yaxis in your first post :grin: .
Thank you for your help @Emmanuelle . I appreciate all your help.

Always a pleasure to help super-users :wink: !