jupyter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
One of the most deceptively-power features of interactive visualization using Plotly is the ability for the user to reveal more information about a data point by moving their mouse cursor over the point and having a hover label appear.
There are three hover modes available in Plotly. The default setting is layout.hovermode='closest'
, wherein a single hover label appears for the point directly underneath the cursor.
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color="country", title="layout.hovermode='closest' (the default)")
fig.update_traces(mode="markers+lines")
fig.show()
If layout.hovermode='x'
(or 'y'
), a single hover label appears per trace, for points at the same x
(or y
) value as the cursor. If multiple points in a given trace exist at the same coordinate, only one will get a hover label. In the line plot below we have forced markers to appear, to make it clearer what can be hovered over, and we have disabled the built-in Plotly Express hovertemplate
by setting it to None
, resulting in a more compact hover label per point:
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color="country", title="layout.hovermode='x'")
fig.update_traces(mode="markers+lines", hovertemplate=None)
fig.update_layout(hovermode="x")
fig.show()
If layout.hovermode='x unified'
(or 'y unified'
), a single hover label appear, describing one point per trace, for points at the same x
(or y
) value as the cursor. If multiple points in a given trace exist at the same coordinate, only one will get an entry in the hover label. In the line plot below we have forced markers to appear, to make it clearer what can be hovered over, and we have disabled the built-in Plotly Express hovertemplate
by setting it to None
, resulting in a more compact entry per point in the hover label:
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color="country", title="layout.hovermode='x unified'")
fig.update_traces(mode="markers+lines", hovertemplate=None)
fig.update_layout(hovermode="x unified")
fig.show()
The hovermode is a property of the figure layout, so you can select a hovermode no matter how you created the figure, either with plotly.express
or with plotly.graph_objects
. Below is an example with a figure created with plotly.graph_objects
. If you're not familiar with the structure of plotly figures, you can read the tutorial on creating and updating plotly figures.
import plotly.graph_objects as go
import numpy as np
t = np.linspace(0, 2 * np.pi, 100)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t, y=np.sin(t), name='sin(t)'))
fig.add_trace(go.Scatter(x=t, y=np.cos(t), name='cost(t)'))
fig.update_layout(hovermode='x unified')
fig.show()
Hover label text and colors default to trace colors in hover modes other than unified
, and can be globally set via the layout.hoverlabel
attributes. Hover label appearance can also be controlled per trace in <trace>.hoverlabel
.
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color="country", title="Custom layout.hoverlabel formatting")
fig.update_traces(mode="markers+lines")
fig.update_layout(
hoverlabel=dict(
bgcolor="white",
font_size=16,
font_family="Rockwell"
)
)
fig.show()
Plotly Express functions automatically add all the data being plotted (x, y, color etc) to the hover label. Many Plotly Express functions also support configurable hover text. The hover_data
argument accepts a list of column names to be added to the hover tooltip. The hover_name
property controls which column is displayed in bold as the tooltip title.
Here is an example that creates a scatter plot using Plotly Express with custom hover data and a custom hover name.
import plotly.express as px
df_2007 = px.data.gapminder().query("year==2007")
fig = px.scatter(df_2007, x="gdpPercap", y="lifeExp", log_x=True,
hover_name="country", hover_data=["continent", "pop"])
fig.show()
To customize the tooltip on your graph you can use hovertemplate, which is a template string used for rendering the information that appear on hoverbox.
This template string can include variables
in %{variable} format, numbers
in d3-format's syntax, and date
in d3-time-format's syntax. In the example below, the empty <extra></extra>
tag removes the part of the hover where the trace name is usually displayed in a contrasting color. The <extra>
tag can be used to display other parts of the hovertemplate, it is not reserved for the trace name.
Note that a hovertemplate customizes the tooltip text, while a texttemplate customizes the text that appears on your chart.
Set the horizontal alignment of the text within tooltip with hoverlabel.align.
Plotly Express automatically sets the hovertemplate
, but you can set it manually when using graph_objects
.
import plotly.graph_objects as go
fig = go.Figure(go.Scatter(
x = [1,2,3,4,5],
y = [2.02825,1.63728,6.83839,4.8485,4.73463],
hovertemplate =
'<i>Price</i>: $%{y:.2f}'+
'<br><b>X</b>: %{x}<br>'+
'<b>%{text}</b>',
text = ['Custom text {}'.format(i + 1) for i in range(5)],
showlegend = False))
fig.add_trace(go.Scatter(
x = [1,2,3,4,5],
y = [3.02825,2.63728,4.83839,3.8485,1.73463],
hovertemplate = 'Price: %{y:$.2f}<extra></extra>',
showlegend = False))
fig.update_layout(
hoverlabel_align = 'right',
title = "Set hover text with hovertemplate")
fig.show()
import plotly.graph_objects as go
fig = go.Figure(go.Pie(
name = "",
values = [2, 5, 3, 2.5],
labels = ["R", "Python", "Java Script", "Matlab"],
text = ["textA", "TextB", "TextC", "TextD"],
hovertemplate = "%{label}: <br>Popularity: %{percent} </br> %{text}"
))
fig.show()
The following example shows how to format hover template. Here is an example to see how to format hovertemplate in Dash.
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
import math
data = px.data.gapminder()
df_2007 = data[data['year']==2007]
df_2007 = df_2007.sort_values(['continent', 'country'])
bubble_size = []
for index, row in df_2007.iterrows():
bubble_size.append(math.sqrt(row['pop']))
df_2007['size'] = bubble_size
continent_names = ['Africa', 'Americas', 'Asia', 'Europe', 'Oceania']
continent_data = {continent:df_2007.query("continent == '%s'" %continent)
for continent in continent_names}
fig = go.Figure()
for continent_name, continent in continent_data.items():
fig.add_trace(go.Scatter(
x=continent['gdpPercap'],
y=continent['lifeExp'],
name=continent_name,
text=df_2007['continent'],
hovertemplate=
"<b>%{text}</b><br><br>" +
"GDP per Capita: %{y:$,.0f}<br>" +
"Life Expectation: %{x:.0%}<br>" +
"Population: %{marker.size:,}" +
"<extra></extra>",
marker_size=continent['size'],
))
fig.update_traces(
mode='markers',
marker={'sizemode':'area',
'sizeref':10})
fig.update_layout(
xaxis={
'title':'GDP per capita',
'type':'log'},
yaxis={'title':'Life Expectancy (years)'})
fig.show()
go
traces have a customdata
argument in which you can add an array, which outer dimensions should have the same dimensions as the plotted data. You can then use customdata
inside a hovertemplate
to display the value of customdata.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
np.random.seed(0)
z1, z2, z3 = np.random.random((3, 7, 7))
customdata = np.dstack((z2, z3))
fig = make_subplots(1, 2, subplot_titles=['z1', 'z2'])
fig.add_trace(go.Heatmap(
z=z1,
customdata=np.dstack((z2, z3)),
hovertemplate='<b>z1:%{z:.3f}</b><br>z2:%{customdata[0]:.3f} <br>z3: %{customdata[1]:.3f} ',
coloraxis="coloraxis1", name=''),
1, 1)
fig.add_trace(go.Heatmap(
z=z2,
customdata=np.dstack((z1, z3)),
hovertemplate='z1:%{customdata[0]:.3f} <br><b>z2:%{z:.3f}</b><br>z3: %{customdata[1]:.3f} ',
coloraxis="coloraxis1", name=''),
1, 2)
fig.update_layout(title_text='Hover to see the value of z1, z2 and z3 together')
fig.show()
import plotly.graph_objects as go
token = open(".mapbox_token").read() # you need your own token
fig = go.Figure(go.Scattermapbox(
name = "",
mode = "markers+text+lines",
lon = [-75, -80, -50],
lat = [45, 20, -20],
marker = {'size': 20, 'symbol': ["bus", "harbor", "airport"]},
hovertemplate =
"<b>%{marker.symbol} </b><br><br>" +
"longitude: %{lon}<br>" +
"latitude: %{lat}<br>" ))
fig.update_layout(
mapbox = {
'accesstoken': token,
'style': "outdoors", 'zoom': 1},
showlegend = False)
fig.show()
Prior to the addition of hovertemplate
, hover text was controlled via the now-deprecated hoverinfo
attribute.
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4, 5],
y=[2, 1, 6, 4, 4],
hovertext=["Text A", "Text B", "Text C", "Text D", "Text E"],
hoverinfo="text",
marker=dict(
color="green"
),
showlegend=False
))
fig.show()
Plotly supports "spike lines" which link a point to the axis on hover, and can be configured per axis.
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color="country", title="Spike lines active")
fig.update_traces(mode="markers+lines")
fig.update_xaxes(showspikes=True)
fig.update_yaxes(showspikes=True)
fig.show()
Spike lines can be styled per axis as well, and the cursor distance setting can be controlled via layout.spikedistance
.
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
fig = px.line(df, x="year", y="lifeExp", color="country", title="Styled Spike Lines")
fig.update_traces(mode="markers+lines")
fig.update_xaxes(showspikes=True, spikecolor="green", spikesnap="cursor", spikemode="across")
fig.update_yaxes(showspikes=True, spikecolor="orange", spikethickness=2)
fig.update_layout(spikedistance=1000, hoverdistance=100)
fig.show()
See https://plotly.com/python/reference/ for more information and chart attribute options!