plotly.py icon indicating copy to clipboard operation
plotly.py copied to clipboard

add ability to hide missing data from hover tooltip

Open janosh opened this issue 4 years ago • 12 comments

I have a dataframe column with some missing values which I want to include in hover_data. Is it possible to show the column in the hover tooltip only if there's value for the currently hovered point? The current default behavior is to show col_name=%{customdata[0]} for missing values. I think it would be better to show nothing at all.

Screen Shot 2021-12-14 at 13 16 13

import plotly.express as px

df = px.data.gapminder().query("continent=='Oceania'")

df["pop"] = None

fig = px.line(
    df,
    x="year",
    y="lifeExp",
    color="country",
    hover_data=["pop"],
    title="layout.hovermode='closest' (the default)",
)
fig.update_traces(mode="markers+lines")

fig.show()

janosh avatar Dec 14 '21 13:12 janosh

Commenting out these two lines

df["pop"] = None

and/or just this one:

hover_data=["pop"],

removes pop:= %{customdata[0]} from tooltips.

empet avatar Dec 27 '21 09:12 empet

@empet You misunderstood. I do want the population data in the tooltip, just not for points where that data is missing. The line

df["pop"] = None

is just to simulate missing data.

janosh avatar Dec 27 '21 10:12 janosh

@janosh I thought you want remove customdata just for this example, because here if you are dsiplaying fig.data[0], and fig.data[1] you'll see that in both cases the elements of customdata are all None:

'customdata': array([[None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None],
                         [None]], dtype=object)

empet avatar Dec 27 '21 10:12 empet

I know. They're all None because I was too lazy to only set the value for that point to None which is being hovered in the screenshot.

janosh avatar Dec 27 '21 10:12 janosh

I think that a solution is to convert customdata to strings, and set ' ', instead of None:

import numpy as np
import plotly.graph_objects as go
N=24
vals = np.random.randint(1000, 2001, N).astype(str)
#or vals = (7*np.random.rand(24)).astype(str)
                       
I = np.random.randint(0, N, 12)
vals[I]=''

fig=go.Figure(go.Scatter(x=np.arange(0,N), y=4+5*np.random.rand(N), customdata=vals,
              hovertemplate='vals: %{customdata}'))
fig.show()

Unfortunately we cannot access individual elements in customdata to set hovertemplate with an if else , depending on whether an element is ' ', or not.

empet avatar Dec 27 '21 10:12 empet

Is there any other way to slove the problem? l have a stacked line graph with same question, some point missing value in stack and display %{customdata} in hover. i can not convert customdata to strings, and set ' ', in fact this point even not in my dataframe, just because other point in same stack it appeard lije this: image

krieg0102 avatar Aug 18 '22 10:08 krieg0102

Is there any development on this issue? I would also like my hovertip to skip that specific customdata if it's np.nan

lijecaru avatar Aug 18 '22 12:08 lijecaru

I also have the same problem. Will be nice if the package owners will give it high priority.

yaelbh avatar Aug 25 '22 11:08 yaelbh

Ditto.

sarangof avatar Mar 27 '23 22:03 sarangof

I had the same problem but for np.nan values. I did not find a solution online so I'm posting mine. I'm not sure if this is the same problem as the one mentioned in the thread.

If you have NaNs in some of your data and you still want to show the hover tooltip in a correct way. There are two things to do:

  1. Call the data like this in the hovertemplate: %{customdata[0]:}. The important thing is the colon.
  2. Do a fillna with any string when calling your data with missings.

Here is a reprex:

# Load Packages
import plotly.express as px
import numpy as np

# Load data
df = px.data.iris()

# Set 50 values in the column petal_width to np.nan
num_nan_values = 100  # Number of NaN values to set for each column
if 'petal_width' in df.columns:
    nan_indices = np.random.choice(len(df), size=num_nan_values, replace=False)
    df.at[nan_indices, 'petal_width'] = np.nan

# Plot with plotly express
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",
                 size='petal_length', custom_data=[df['petal_width'].fillna("white")])
fig.update_traces(
    hovertemplate='petal width=%{customdata[0]:}<br>label=%{y}')
fig.show()

Instead of Screenshot (4) your tooltip will look like this

Screenshot (3)

gl2324 avatar Sep 27 '23 13:09 gl2324