1

I am trying to generally recreate this graph and struggling with adding a column to the hovertemplate of a plotly Scatter. Here is a working example:

import pandas as pd
import chart_studio.plotly as py
import plotly.graph_objects as go

dfs = pd.read_html('https://coronavirus.jhu.edu/data/mortality', header=0)
df = dfs[0]
percent = df['Case-Fatality'] # This is my closest guess, but isn't working
fig = go.Figure(data=go.Scatter(x=df['Confirmed'],
                               y = df['Deaths'],
                               mode='markers',
                               hovertext=df['Country'],
                               hoverlabel=dict(namelength=0),
                               hovertemplate = '%{hovertext}<br>Confirmed: %{x}<br>Fatalities: %{y}<br>%{percent}',
                               
                               ))
fig.show()

I'd like to get the column Cast-Fatality to show under {percent}

I've also tried putting in the Scatter() call a line for text = [df['Case-Fatality']], and switching {percent} to {text} as shown in this example, but this doesn't pull from the dataframe as hoped.

I've tried replotting it as a px, following this example but it throws the error dictionary changed size during iteration and I think using go may be simpler than px but I'm new to plotly.

Thanks in advance for any insight for how to add a column to the hover.

ncraig
  • 783
  • 1
  • 10
  • 23
  • If the suggestion you have received was useful, please consider to upvote and/or mark it as the accepted answer! – vestland Jul 10 '20 at 21:18
  • I'd like to but SO is making me wait a day to accept my answer which is working. – ncraig Jul 10 '20 at 21:20
  • The upvote buttons for the answers that helped you build your own solution is still working, right? – vestland Jul 10 '20 at 21:51

3 Answers3

3

As the question asks for a solution with graph_objects, here are two that work-

Method (i)

Adding %{text} where you want the variable value to be and passing another variable called text that is a list of values needed in the go.Scatter() call. Like this-

percent = df['Case-Fatality']
hovertemplate = '%{hovertext}<br>Confirmed: %{x}<br>Fatalities: %{y}<br>%{text}',text = percent

Here is the complete code-

import pandas as pd
import plotly.graph_objects as go

dfs = pd.read_html('https://coronavirus.jhu.edu/data/mortality', header=0)
df = dfs[0]
percent = df['Case-Fatality'] # This is my closest guess, but isn't working
fig = go.Figure(data=go.Scatter(x=df['Confirmed'],
                               y = df['Deaths'],
                               mode='markers',
                               hovertext=df['Country'],
                               hoverlabel=dict(namelength=0),
                               hovertemplate = '%{hovertext}<br>Confirmed: %{x}<br>Fatalities: %{y}<br>%{text}',
                               text = percent))
fig.show()

Method (ii)

This solution requires you to see the hoverlabel as when you pass x unified to hovermode. All you need to do then is pass an invisible trace with the same x-axis and the desired y-axis values. Passing mode='none' makes it invisible. Here is the complete code-

import pandas as pd
import plotly.graph_objects as go

dfs = pd.read_html('https://coronavirus.jhu.edu/data/mortality', header=0)
df = dfs[0]
percent = df['Case-Fatality'] # This is my closest guess, but isn't working
fig = go.Figure(data=go.Scatter(x=df['Confirmed'],
                               y = df['Deaths'],
                               mode='markers',
                               hovertext=df['Country'],
                               hoverlabel=dict(namelength=0)))
fig.add_scatter(x=df.Confirmed, y=percent, mode='none')
fig.update_layout(hovermode='x unified')
fig.show()
callmeanythingyouwant
  • 1,789
  • 4
  • 15
  • 40
2

The link you shared is broken. Are you looking for something like this?

import pandas as pd
import plotly.express as px

px.scatter(df,
           x="Confirmed",
           y="Deaths",
           hover_name="Country",
           hover_data={"Case-Fatality":True})

Then if you need to use bold or change your hover_template you can follow the last step in this answer

rpanai
  • 12,515
  • 2
  • 42
  • 64
  • 1. Sorry, I can't find a broken link in my question. There are two and they both work at my end. 2. Thank you for offering the code, but it produced the same error `dictionary changed size during iteration` I described above. – ncraig Jul 10 '20 at 14:58
  • Which version of plotly are you using? Please add the output of `plotly.__version__` – rpanai Jul 10 '20 at 15:02
  • The broken link was this [https://coronavirus.jhu.edu/data/mortality](https://coronavirus.jhu.edu/data/mortality). But now it's working. Do you mind to specify the plot you want to recreate? – rpanai Jul 10 '20 at 15:04
  • Taking a bit from your answer and a bit from the answer to another question I've arrived at a solution. Thank you for your contribution. – ncraig Jul 10 '20 at 15:07
  • For the sake of learning, I'm still keen to understand how to accomplish this with plotly `go` using `hovertemplate` but I'll keep poking around. – ncraig Jul 10 '20 at 15:12
  • Do you mind to share the link of the other question that was useful to you? Eventually you can add your answer but please don't forget to upvote all the answers were useful to you. – rpanai Jul 10 '20 at 15:54
0

Drawing inspiration from another SO question/answer, I find that this is working as desired and permits adding multiple cols to the hover data:

import pandas as pd
import plotly.express as px

fig = px.scatter(df,
           x="Confirmed",
           y="Deaths",
           hover_name="Country",
           hover_data=[df['Case-Fatality'], df['Deaths/100K pop.']])
fig.show()
ncraig
  • 783
  • 1
  • 10
  • 23
  • 1
    Sorry I don't understand. In any part of your question you asked to add 'Deaths/100K pop.' And this could easily achieved adding `hover_data={"Case-Fatality":True, 'Deaths/100K pop.':True}` in my answer. – rpanai Jul 10 '20 at 15:59
  • Sorry if there was a lack of clarity. The addition of `Deaths/100K pop.` was something I discovered and was not part of the initial question. However, the solution I stumbled on illustrated how to include several fields so I mentioned that as an addition. Also, the `hover_data={"Case-Fatality":True}` and `hover_data={"Case-Fatality":True, 'Deaths/100K pop.':True}` methods both return the error I mentioned both in my question and the comments below `dictionary changed size during iteration`. I'm not sure why these data produce that error because I see your suggestion follows `px` documentation. – ncraig Jul 10 '20 at 19:15
  • 1
    Did you check your `plotly.__version__`? Cos I can't reproduce your error. – rpanai Jul 10 '20 at 19:19
  • `from plotly import __version__` and then `print(__version__)` returned `4.4.1` – ncraig Jul 10 '20 at 21:14
  • 1
    Latest version is `4.8.1` I guess that if you update your package you'll get rid of the errors. Plus from `4.7.0` plotly got an important speed-up boost. – rpanai Jul 10 '20 at 23:35
  • I wonder if it's possible to do this without Plotly Express, i.e. using go.Figure() which has much more flexibility. – fazistinho_ Oct 16 '20 at 09:40
  • @fazistinho_ It is, check out my solution – callmeanythingyouwant Jun 05 '21 at 12:36