Search code examples
pythonpandasplotly

Pandas plot with Plotly backend and Custom Hover template


I am trying to include additional data in the hover template, similar to this Plotly: Including additional data in hovertemplate, but using Plotly plotting backend on Pandas.

I have two 2D Pandas data frames, the first is the population by country and by year, and the second is the percent population growth by country and by year, generated with the following codes.

import pandas as pd
pd.options.plotting.backend = 'plotly'

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
df_pop = df.pivot_table(index='year', columns='country', values='pop').copy()
df_pct_growth = df_pop.pct_change().fillna(0) * 100

df_pop: enter image description here

df_pct_growth: enter image description here


I visualized the population for each country as follows. As you can see, the hover text only has the country, year, and population. I want to add the % growth from the df_pct_growth into the hover text. Does anyone know how to do that?

df_pop.plot(labels=dict(value='Population'))

enter image description here


Solution

  • I have not seen any examples of using custom data with the 'Plotly' backend. Looking at the graph structure, I thought it might be possible to add custom data and update the hover template. The code I added would set the country name to meta. (which could provide the same functionality as the custom data) and set the column data for the growth rate by country as custom data. The hover template was accomplished by adding a growth rate field.

    import plotly.express as px
    import pandas as pd
    pd.options.plotting.backend = 'plotly'
    
    df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
    df_pop = df.pivot_table(index='year', columns='country', values='pop').copy()
    df_pct_growth = df_pop.pct_change().fillna(0) * 100
    
    fig = df_pop.plot(labels=dict(value='Population'))
    
    for i,country in enumerate(df.country.unique()):
        fig.data[i]['meta'] = country
        fig.data[i]['customdata'] = df_pct_growth.loc[:,country].to_frame().values
        fig.data[i]['hovertemplate'] = 'country: %{meta}<br>year: %{x}<br>population: %{y:,}<br>growth: %{customdata[0]:.2f}<extra></extra>'
    
    fig.show()
    

    enter image description here

    Plotly code without backend

    import plotly.graph_objects as go
    
    fig = go.Figure()
    
    for country in df.country.unique():
        dff = df.query('country == @country')
        fig.add_trace(go.Scatter(x=dff['year'],
                                 y=dff['pop'],
                                 mode='lines',
                                 name=country,
                                 meta=country,
                                 customdata=df_pct_growth.loc[:,country].to_frame().values,
                                 hovertemplate=
                                 'country: %{meta}<br>' + 
                                 'year: %{x}<br>' +
                                 'population: %{y:,}<br>' +
                                 'growth: %{customdata[0]:.2f}' + 
                                 '<extra></extra>'
                             ))
    fig.show()