python plotly: how to display additional label on hover

Question:

I have two area subplots and when I hover over the plot, it displays the value of Val_2 and Val_Yellow. The dataframe contains a column called "Diff" that is the difference between Val_2 and Val_Yellow. How can I display Diff and its value in the bottom of the same white hover-box where Val_2 and Val_Yellow are displayed?

enter image description here

Here is the reproducible code:

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots 

rng = pd.date_range('2022-04-09', periods=20, freq='D')
np.random.seed(42)
first_df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))}) 
first_df['Type'] = 'A'

second_df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))}) 
second_df['Type'] = 'B'

final_df =  pd.concat([first_df,second_df]).sort_values(by = 'Date')
final_df['Is_Weekend'] = np.where((final_df['Date'].dt.weekday == 5), 1, 0 )

final_df['Val_2'] = final_df['Val'] * 3
final_df['Diff'] = final_df['Val'] - final_df['Val_2']

A_df = final_df[final_df['Type']=='A']
B_df = final_df[final_df['Type']=='B']

fig = make_subplots(rows=2, cols=1,
                    vertical_spacing = 0.05,
                    shared_xaxes=True)
fig.add_trace(go.Scatter(
    x = A_df['Date'], 
    y = A_df['Val'],
    fill=None,
    mode='lines+markers',
    line_color='orange', showlegend=True, name = "Val_Yellow"),
            row = 1, col = 1)
fig.add_trace(go.Scatter(
    x =  A_df['Date'], 
    y = A_df['Val_2'],
    fill='tonexty', # fill area
    mode='lines+markers', line_color='red', showlegend=False, name ="Val_2"),
            row = 1, col = 1)
fig.update_xaxes(showgrid=False, row=1, col=1)


fig.add_trace(go.Scatter(
    x = B_df['Date'], 
    y = B_df['Val'],
    fill=None,
    mode='lines+markers',
    line_color='blue', showlegend=True, name = "Val_Blue"),
            row = 2, col = 1)

fig.add_trace(go.Scatter(
    x =  B_df['Date'], 
    y = B_df['Val_2'],
    fill='tonexty', # fill area
    mode='lines+markers', line_color='red', showlegend=True, name ="Val_2"),
            row = 2, col = 1)

fig.update_yaxes(tickprefix = "$")

fig.update_layout(hovermode='x unified', xaxis_range=[A_df['Date'].iloc[0], A_df['Date'].iloc[len(A_df)-1]])
Asked By: user9532692

||

Answers:

You can use customdata to pass additional data for the hovertemplate to access. You will need to pass the "Diff" column from your dataframes into go.Scatter and then modify the hovertemplate to access the customdata.

For example, I added customdata and hovertemplate arguments to your first go.Scatter trace:

fig.add_trace(go.Scatter(
    x = A_df['Date'], 
    y = A_df['Val'],
    customdata = A_df['Diff'],
    hovertemplate = '%{y:$}<br>Diff:%{customdata:$}',
    fill=None,
    mode='lines+markers',
    line_color='orange', showlegend=True, name = "Val_Yellow"),
            row = 1, col = 1)

I did the same for your third trace as well.

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots 

rng = pd.date_range('2022-04-09', periods=20, freq='D')
np.random.seed(42)
first_df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))}) 
first_df['Type'] = 'A'

second_df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))}) 
second_df['Type'] = 'B'

final_df =  pd.concat([first_df,second_df]).sort_values(by = 'Date')
final_df['Is_Weekend'] = np.where((final_df['Date'].dt.weekday == 5), 1, 0 )

final_df['Val_2'] = final_df['Val'] * 3
final_df['Diff'] = final_df['Val'] - final_df['Val_2']

A_df = final_df[final_df['Type']=='A']
B_df = final_df[final_df['Type']=='B']

fig = make_subplots(rows=2, cols=1,
                    vertical_spacing = 0.05,
                    shared_xaxes=True)
fig.add_trace(go.Scatter(
    x = A_df['Date'], 
    y = A_df['Val'],
    customdata = A_df['Diff'],
    hovertemplate = '%{y:$}<br>Diff:%{customdata:$}',
    fill=None,
    mode='lines+markers',
    line_color='orange', showlegend=True, name = "Val_Yellow"),
            row = 1, col = 1)
fig.add_trace(go.Scatter(
    x =  A_df['Date'], 
    y = A_df['Val_2'],
    fill='tonexty', # fill area
    mode='lines+markers', line_color='red', showlegend=False, name ="Val_2"),
            row = 1, col = 1)
fig.update_xaxes(showgrid=False, row=1, col=1)


fig.add_trace(go.Scatter(
    x = B_df['Date'], 
    y = B_df['Val'],
    customdata = B_df['Diff'],
    hovertemplate = '%{y:$}<br>Diff:%{customdata:$}',
    fill=None,
    mode='lines+markers',
    line_color='blue', showlegend=True, name = "Val_Blue"),
            row = 2, col = 1)

fig.add_trace(go.Scatter(
    x =  B_df['Date'], 
    y = B_df['Val_2'],
    fill='tonexty', # fill area
    mode='lines+markers', line_color='red', showlegend=True, name ="Val_2"),
            row = 2, col = 1)

fig.update_yaxes(tickprefix = "$")

fig.update_layout(hovermode='x unified', xaxis_range=[A_df['Date'].iloc[0], A_df['Date'].iloc[len(A_df)-1]])

enter image description here

Answered By: Derek O