I've actually had the similar problem, and trust me it took me 2 and a half hour to figure out. Let's understand with an example.
fig = make_subplots(rows=1,cols=2,subplot_titles=('First plot','Second plot'),
specs=[[{'type': 'scene'}, {'type': 'scene'}]])
fig.add_trace(go.Scatter3d(x=[0,1,2,3],y=[0,1,2,3],z=[0,1,2,3]), row=1,col=1)
fig.add_trace(go.Scatter3d(x=[0,1,2,3],y=[0,1,2,3], z=[0,1,2,3]), row=1,col=2)
fig.update_layout(title='Add Custom Data')
fig.show()
This will create simple two scatter3d plots, where hoverdata is x,y and z axis. Now you want to add the data m=[9,8,7,6,5]
to first plot. you can parse m
in text
argument and add hovertemplate
as well.
fig.add_trace(go.Scatter3d(x=[0,1,2,3],y=[0,1,2,3],z=[0,1,2,3],
text=[9,8,7,6], hovertemplate='<br>x:%{x}<br>y:%{y}<br>z:%{z}<br>m:%{text}'), row=1,col=1)
This should work just fine. But now we want to add one more list say n=[5,6,7,8]
to the first plot (or any). We will use customdata
argument this time.
fig.add_trace(go.Scatter3d(x=[0,1,2,3],y=[0,1,2,3],z=[0,1,2,3],
text=[9,8,7,6],customdata=[5,6,7,8],
hovertemplate='<br>x:%{x}<br>y:%{y}<br>z:%{z}<br>m:%{text}<br>n:%{customdata}'), row=1,col=1)
Now what if we want to add our 3rd list of custom data. Here comes the tricky part. You cannot parse the list of two lists in the custom data, and then call customdata[0]
and customdata[1]
, it's not that simple. our 3rd list is k=[2,4,6,8]
.
We need customdata=[[[5],[2]],[[6],[4]],[[7],[6]],[[8],[8]]]
like this and it should work fine. Basically we need to give plotly a single list (or array) where in each element it's the list of all points you want to show.
fig.add_trace(go.Scatter3d(x=[0,1,2,3],y=[0,1,2,3],z=[0,1,2,3],
text=[9,8,7,6],customdata=[[[5],[2]],
[[6],[4]],
[[7],[6]],
[[8],[8]]],
hovertemplate='<br>x:%{x}<br>y:%{y}<br>z:%{z}<br>m:%{text}<br>n:%{customdata[0]}<br>k:%{customdata[1]}'), row=1,col=1)
We almost done, but there is one thing left. It's lots of work to manually create list like we given in customdata, therefore we'll automate it using powerful library import numpy as np
n = [5,6,7,8]
k = [2,4,6,8]
nk = np.empty(shape=(4,2,1), dtype='object')
nk[:,0] = np.array(n).reshape(-1,1)
nk[:,1] = np.array(k).reshape(-1,1)
fig.add_trace(go.Scatter3d(x=[0,1,2,3],y=[0,1,2,3],z=[0,1,2,3],
text=[9,8,7,6],customdata=nk,
hovertemplate='<br>x:%{x}<br>y:%{y}<br>z:%{z}<br>m:%{text}<br>n:%{customdata[0]}<br>k:%{customdata[1]}'), row=1,col=1)
BOOM !
You can parse df['Column name']
in place of np.array(n)
if you want to add data directly from dataframe.
'<br>%Change: %{text}'
and specifying in the bracketstext=group_dfff.PERC_CHANGE
- this worked as I wanted. However, text var is a builtin thingie so I am still not sure how would I go about adding let's say forth, fifth and more labels that I would want to have upon hovering the datapoint... – Xanthic