Double pie with multiple labels

Hi everyone,

On the image below you can see a double pie. The outtest part is supposed to be divided in each meal of the day for each macronutriment (carbohydrate, lipid, protein). To make it even clearer I would like to label it with Meal 1, Meal 2, Meal 3 depending on the number of the meal. But I don’t how to do it. For me there is two options, first is legend, so I will have for example Meal 1, Meal 2, Meal 3 three times (for each color/ Macronutriments). And the second option is to write it into the outtest pie. I don’t which one is the more convenient to code. The second one seems nicer for me because I have less legend to display but is it doable, that’s why I decided to open a topic if somebody knows how to one of the method or any other which I’m open to anything. I will also provide my code for the sake of simplicity even if there is some missing variable I guess.

def display_macro_pie(data):
‘’’
metter les outside color en light
changer les pourcentages qui sont toto en pourcentage des protéines
‘’’
labels = [‘Protéine’,‘Glucide’,‘Lipide’]

nb_meal = 0
for x in data.columns.values:
    if type(x)==int:
        nb_meal+=1

outer_values = [data[ data.labels == "Protéine"][[i for i in range(1,nb_meal+1)]].values[0].sum()]+ [data[ data.labels == "Glucide"][[i for i in range(1,nb_meal+1)]].values[0].sum()] + [data[ data.labels == "Lipide"][[i for i in range(1,nb_meal+1)]].values[0].sum()]
inner_values = data[ data.labels == "Protéine"][[i for i in range(1,nb_meal+1)]].values[0].tolist() + data[ data.labels == "Glucide"][[i for i in range(1,nb_meal+1)]].values[0].tolist() + data[ data.labels == "Lipide"][[i for i in range(1,nb_meal+1)]].values[0].tolist()

c = px.colors.qualitative 

# outter pie
trace1 = go.Pie(
    hole=0.5,
    sort=False,
    direction='clockwise',
    values=inner_values,
    textinfo= 'percent',
    textposition='outside',
    marker={'colors': ['green']*nb_meal + ["red"]*nb_meal + ['blue']*nb_meal,
            'line': {'color': 'white', 'width': 1}}, 
    title=dict(text='Measured',
                 position='top center'
                 ),
    showlegend = False
)

# inner pie
trace2 = go.Pie(
    hole=0.7,
    sort=False,
    direction='clockwise',
    values=outer_values,
    domain={'x': [0.15, 0.85], 'y': [0.15, 0.85]},
    labels=labels,
    textinfo='label + percent',
    textposition='inside',
    marker={'colors': ["green", 'red', 'blue'],
            'line': {'color': 'white', 'width': 1}}
)

# inner inner pie
trace3 = go.Pie(
    hole=0.7,
    sort=False,
    direction='clockwise',
    values=data["Objectif"],
    domain={'x': [0.29, 0.71], 'y': [0.29, 0.71]},
    labels=labels,
    textinfo='label + percent',
    textposition='inside',
    name = "Objective",
    title=dict(text='Reference',
                 position='top center'
                 ),
    marker={'colors': ["green", 'red', 'blue'],
            'line': {'color': 'white', 'width': 1}}
)


fig = go.FigureWidget(data=[trace1, trace2, trace3])
fig.update_layout(autosize=False,width=600,height=600)
return fig

I wish you a great day ! Thank you for your help

Hey again Plotlyoko

As a suggestion you should take a look at the sunburst charts. They might be more useful for some of the things you’re trying to achieve.

They give you interactivity to the graphs as well as let you drill into data and they work great with hierarchical data . They will probably be way cleaner and more useful for you.

You could probably get away with using the px.sunburst for what you’re trying to do. Might not for that very center pie char but I’m not 100% sure what you’re trying to achieve with that part but if you really want a hole in the center of the sunburst chart there’s a hacky way you can do it.

Here’s no hole:

import plotly.express as px
df = px.data.tips()

fig = px.sunburst(df, path=['sex', 'smoker', 'time'], values='total_bill')

fig.show()

pie1

Then here’s the hacky way to add a hole

import plotly.express as px
df = px.data.tips()

fig = px.sunburst(df.assign(hole=' '), path=['hole','sex', 'smoker', 'time'], values='total_bill')

fig.show()

Essentially you create new column that has nothing in it and it displays nothing in the middle creating that same hole
pie2

I’d suggest just copy pasting my code and try generating it yourself so you can see what I mean by interactivity. Then with that you can create a max depth level and go much deeper to the data each time you click. I’m not 100% if this is what you’re looking for but it might give you another idea.

Thanks
Payton

1 Like