Black Lives Matter. Please consider donating to Black Girls Code today.

Help with Sunburst using Plotly Express and path

Hi

Plotly Express with the path argument makes it really easy to create Sunburst Charts. Thanks for this new addition in 4.5!

I have 2 questions:

In the function below, the column names for the path are updated from a dropdown. I would like to include a description for the column in the hovertemplate. For example, if you hover over UK I would like it to show “United Kingdom” I tried using names= with the column name that contains the descriptions, but I couldn’t get it to work. An example would be really helpful.

Also, if the values are zero the labels show up in very strange looking overlapping text. How do I get rid of that? I’m using: uniformtext=dict(minsize=10, mode=‘hide’) but it only seems to hide small non-zero values.

def make_sunburst(wb, balance, path):
    figure = px.sunburst(wb, path=path, values=balance)    
    figure.update_traces(
        go.Sunburst(hovertemplate=' $: %{value}'),
        insidetextorientation='radial',       
    )
    figure.update_layout(
        margin=dict(t=10, l=0, r=0, b=0),                        
        uniformtext=dict(minsize=10, mode='hide'),
        paper_bgcolor='whitesmoke'
    )   
    return figure

Hi @AnnMarieW for the first point, did you try using the hover_data argument with your label column (as in this example https://plot.ly/python/sunburst-charts/#sunburst-of-a-rectangular-dataframe-with-continuous-color-argument-in-pxsunburst)?

For the second point, I think this is a bug or at least an undesired behaviour. I could reproduce it with the following example (try it uncommenting the line where values are set to 0).

import plotly.express as px
df = px.data.tips()
# This line does not work with uniformtext
# df['total_bill'][df['sex'] == 'Male'] = 0
df['total_bill'][df['sex'] == 'Male'] = 0.001
fig = px.sunburst(df, path=['day', 'time', 'sex'], values='total_bill')
fig.update_layout(uniformtext=dict(minsize=10, mode='hide'))
fig.show()

Any chance that you could set your 0 values to a very small number here? (It could be as small as 1.e-6 for example, maybe even smaller). It could be a workaround while this behaviour gets fixed.

Hi Emmanuelle,

I got hover_data to work for the out ring. Thanks! But just like in your example, there is a ? if you hover over the inner ring. I tried using 2 column names in the hover_data, but that didn’t work. Can you have hover_data for each ring?

Good suggestion to set the zero values to a small number - that works for now.

Thanks for your quick reply (and Dash is awesome :slight_smile:

Thanks for your kind words :-). For the record I opened https://github.com/plotly/plotly.js/issues/4569

For the hover data, there is the question of how to create the hover of a parent sector because it’s not defined in the user-provided data. What we do now is that if all children have the same value we pass this value to the parent, otherwise we put a (?) (non-defined). Would you have expected another behavior? Feedback is very welcome!

Thanks for opening the ticket.

It would be ideal to specify the column for the hover data for each column in the path. Then it would be possible to do things such as show the extended descriptions for each ring.

Just in case anyone was looking for an example of the syntax to add hover_data to the hovertemplate, here is an example and an image of the results. (It also shows the workaround to clean up the labels - it looks much better!)

Thanks again for your help :grinning:

def make_sunburst(wb, balance, path):
    figure = px.sunburst(wb, path=path, values=balance, hover_data=['Holding'])    
    figure.update_traces(
        go.Sunburst(hovertemplate='<b>%{label} </b> <br>%{customdata[0]}<br> $%{value:,.0f}'),
        insidetextorientation='radial',       
    )
    figure.update_layout(
        margin=dict(t=10, l=0, r=0, b=0),                        
        uniformtext=dict(minsize=10, mode='hide'),
        paper_bgcolor='whitesmoke'
    )   
    return figure

Hi @AnnMarieW ok I see what you mean. I’m not sure we want to implement this feature (having one hover column per path column) in plotly.express because this is not something we do in other px functions (and we would have some corner cases to handle, like what should be done when there are different hover values specified for the same sector of an inner ring?). You can do two things to have this behaviour

  • use the id/parent syntax (either with graph_objects or px) instead of the path syntax, where you can give a hover value for each id
  • create the figure with px and path, and modify the customdata array which is used for the hover as in the example below
import plotly.express as px
import numpy as np
df = px.data.tips()
fig = px.sunburst(df, path=['sex', 'day', 'time'], values='total_bill', color='day', hover_data=['smoker'])
fig.data[0].customdata[:, 0] = np.random.random(21).astype(str) # dummy data
fig.show()

(I would probably use the second solution :-))

That makes sense - and I agree, I think the second solution will be easier to implement.

Thanks so much for the example. I spend a lot of time reading documentation, but since I’m still a newbie, it usually doesn’t make sense to me until I can see some examples. I appreciate all the examples in the Dash and Plotly tutorials too.

1 Like