Plotly: Including additional data in hovertemplate

Question:

enter image description here hovertemplate=
‘Continent: %{df[‘continent’]}
‘+
‘Country: %{df[‘country’]}
‘+
‘gdpPercap: %{x:,.4f}
‘+
‘lifeExp: %{y}’+

I’m trying to use hovertemplate to customize hover information. However I can’t get it to display what I want. I am getting x & y to work well. I can’t figure out how to add other fields to the hovertemplate though. Any help would be appreciated.

import numpy as np
df = df[df['year'] == 1952]
customdata = np.stack((df['continent'], df['country']), axis=-1)
fig = go.Figure()
for i in df['continent'].unique():
    df_by_continent = df[df['continent'] == i]
    fig.add_trace(go.Scatter(x=df_by_continent['gdpPercap'], 
                         y=df_by_continent['lifeExp'],
                         mode='markers',
                         opacity=.7,
                         marker = {'size':15},
                         name=i,
                         hovertemplate=
                            'Continent: %{customdata[0]}<br>'+
                            'Country: %{customdata[1]}<br>'+
                            'gdpPercap: %{x:,.4f} <br>'+
                            'lifeExp: %{y}'+
                             '<extra></extra>',
                            ))
fig.update_layout(title="My Plot",
                 xaxis={'title':'GDP Per Cap',
                       'type':'log'},
                 yaxis={'title':'Life Expectancy'},
                )
fig.show()

Updated with more code. The first answer didn’t work just returning the text value of comdata.

Asked By: David 54321

||

Answers:

For any other variables besides {x} and {y} in the hovertemplate string, you’ll want to create a variable called customdata which is a numpy array of the DataFrame columns (df['continent'], df['country'] in your case), and pass customdata=customdata to fig.update_layout. This is suggested by @empet in his Plotly forum answer here.

You can try something like:

import numpy as np
import pandas as pd
import plotly.express as px

df = px.data.gapminder()

customdata = np.stack((df['continent'], df['country']), axis=-1)

fig = px.scatter(df, x="gdpPercap", y="lifeExp")

hovertemplate = ('Continent: %{customdata[0]}<br>' + 
    'Country: %{customdata[1]}<br>' + 
    'gdpPercap: %{x:,.4f} <br>' + 
    'lifeExp: %{y}' + 
    '<extra></extra>')

fig.update_traces(customdata=customdata, hovertemplate=hovertemplate)
fig.show()

enter image description here

Answered By: Derek O

See below for an additional example of how to use customdata with multiple traces based on the code included in your question. Note that you actually need to add the customdata to the figure traces in order to use it in the hovertemplate, this was also shown in Derek O‘s answer.

import numpy as np
import pandas as pd
import plotly.graph_objects as go

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
df = df[df['year'] == 1952]

fig = go.Figure()

for continent in df['continent'].unique():

    df_by_continent = df[df['continent'] == continent]

    fig.add_trace(
        go.Scatter(
            x=df_by_continent['gdpPercap'],
            y=df_by_continent['lifeExp'],
            customdata=np.stack((df_by_continent['country'], df_by_continent['pop']), axis=-1),
            mode='markers',
            opacity=0.7,
            marker={'size': 15},
            name=continent,
            hovertemplate='<b>Country</b>: %{customdata[0]}<br>' +
                          '<b>Population</b>: %{customdata[1]:,.0f}<br>' +
                          '<b>GDP</b>: %{x:$,.4f}<br>' +
                          '<b>Life Expectancy</b>: %{y:,.2f} Years' +
                          '<extra></extra>',
        )
    )

fig.update_layout(
    xaxis={'title': 'GDP Per Cap', 'type': 'log'},
    yaxis={'title': 'Life Expectancy'},
)

fig.write_html('fig.html', auto_open=True)

enter image description here

Answered By: Flavia Giammarino

A variation of the previous answers using just pandas/python:

customdata = list(df[['continent','country']].to_numpy())

Then compose your figure with a template referring to customdata as in the other answers. For variation here’s an example with Scatter3D and adding data from two columns of a dataframe:

import plotly.graph_objects as go

customdata_set = list(df[['transaction','type']].to_numpy())

fig = go.Figure(
    data=[go.Scatter3d(x=df.time,
                       y=df.source,
                       z=df.dest,
                       hovertemplate='<i>Source:</i>: %{y:i}<br>' +
                       '<i>Destination:</i>: %{z:i}<br>' +
                       '<i>Amount:</i>: $%{text}<br>' +
                       '<i>Txn #:</i>: %{customdata[0]}<br>' +
                       '<i>Txn Type:</i>: %{customdata[1]}<br>' +
                       '<i>Date:</i>: %{x|%Y-%m-%d}',
                       text=(df.amount).to_numpy(),
                       customdata = customdata_set,
                       mode='markers',
                       marker=dict(
                            color=moat_sql.tx_amount,
                            size=4,
                            opacity=.8,
                            showscale=True,
                            colorscale='Viridis',
                            colorbar=dict(
                                title=dict(text='Log Txn Amount',
                                           side='bottom',
                                           font={'color': 'red'}
                                           )
                            )
    )
    )]
)
Answered By: MikeB2019x

Instead of using customdata + hovertemplate, you can just pass formatted text to the text parameter directly. I found this simpler, and more powerful – for example if you don’t want the exact same formatting for all elements.

So this actually works:

text = your_df.map(
    lambda row: f'<i>Source:</i>: %{row.source:i}<br>' +
                    f'<i>Destination:</i>: %{row.z:i}<br>' +
                    f'<i>Amount:</i>: $%{row.amount}<br>' +
                    f'<i>Txn #:</i>: %{row.txn}<br>' +
                    f'<i>Txn Type:</i>: %{row.txn_type}<br>' +
                    f'<i>Date:</i>: %{row.date|%Y-%m-%d}',
    axis='columns'
)

go.Scatter3d(
   ...,
   text=text,
   ...
)

The text element doesn’t support full HTML, but I’ve seen it support at least the <br> and <b> tags.
It does not seem to support <h1>, <nbsp>, <hr> tags.

I believe the same is true for hovertemplate.

Answered By: Zoltán

here is an example in Javascript using Plotly.js in case anyone is looking for it.:

<!DOCTYPE html>
<html>
<head><script src="https://cdn.plot.ly/plotly-2.14.0.min.js"></script></head>
<body>
    <div id="myDiv" style="width: 100%; height: 100%;"></div>
    <script>
        // Define custom data
        const customData = [
            {
                x: [1, 2, 3],
                y: [4, 5, 6],
                z: ["Potato", "Banana", "Tomato"]
            }
        ];

        // Define custom hovertemplate
        const customHovertemplate = "X: %{x}<br>Y: %{y}<br>Z: %{customdata}";

        // Define trace using custom data and hovertemplate
        const trace = {
            x: customData[0].x,
            y: customData[0].y,
            customdata: customData[0].z,
            mode: "markers",
            marker: { color: "blue", size: 12 },
            type: "scatter",
            hovertemplate: customHovertemplate
        };

        Plotly.newPlot("myDiv", [trace]);
    </script>
</body>
</html>

Answered By: christian
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.