Plotly:如何在不更改数据源的情况下更改 go.pie 图表的图例?

Plotly: How to change legend for a go.pie chart without changing data source?

我正在练习使用 Python 在 Plotly Express 中构建饼图。
所以,这是我制作的饼图;

此图表是根据一个包含两列的文件生成的,该文件名为

  1. gender 值为 [0, 1, 2]
  2. count_genders 值为 [total_count_0, total_count_1, total_count_2]

我打算为这些值添加一些描述;例如

这是我目前卡住的地方。
如果我没记错的话,如果您想更改图例中的标签(至少在 Choropleth 地图中),您可以操纵位于 colorscale 栏中的 ticks。通过操纵它们,您可以重命名有关数据的标签。因此,我想知道您是否可以在饼图中做同样的事情?

我当前的图表代码:

import pandas as pd
import plotly.express as px
            
'''
Pandas DataFrame:
'''
users_genders = pd.DataFrame({'gender': {0: 0, 1: 1, 2: 2},
               'count_genders': {0: 802420, 1: 246049, 2: 106}})

''' Pie Chart Viz '''
gender_distribution = px.pie(users_genders,
                             values='count_genders',
                             names='gender',
                             color_discrete_map={'0': 'blue',
                                                 '1': 'red',
                                                 '2': 'green'},
                             title='Gender Distribution <br>'
                                   'between 2006-02-16 to 2014-02-20',
                             hole=0.35)
gender_distribution.update_traces(textposition='outside',
                                  textinfo='percent+label',
                                  marker=dict(line=dict(color='#000000',
                                                        width=4)),
                                  pull=[0.05, 0, 0.03],
                                  opacity=0.9,
                                  # rotation=180
                                  )
gender_distribution.update_layout(legend=dict({'traceorder': 'normal'}
                                              # ticks='inside',
                                              # tickvals=[0, 1, 2],
                                              # ticktext=["0 - Female",
                                              #           "1 - Male",
                                              #           "2 - Undefined"],
                                              # dtick=3
                                              ),
                                   legend_title_text='User Genders')
gender_distribution.show()

我尝试在 update_layout 中添加 ticks 无济于事。它 returns 关于不正确参数的错误消息。有人可以帮我解决这个问题吗?

edit 1:如果我不清楚,我想知道是否可以修改图例中显示的值而不更改文件中的原始值。非常感谢您花时间帮助那些已经足够好心帮助我解决此问题的人!

编辑 2:添加代码的导入和其他先前的细节,删除 Dropbox link.

如果我对你的问题的理解正确,你想更改图例中显示的内容而不更改数据源中的名称。可能有更优雅的方法来做到这一点,但我已经组合了一个自定义函数 newLegend(fig, newNames) 可以为您做到这一点。

所以有了这样的图:

...运行:

fig = newLegend(fig = fig, newNames = {'Australia':'Australia = Dangerous',
                                       'New Zealand' : 'New Zealand = Peaceful'})

...会给你:

我希望这就是您要找的。如果没有,请随时告诉我!

完整代码:

import plotly.express as px

df = px.data.gapminder().query("continent == 'Oceania'")
fig = px.pie(df, values='pop', names='country')
fig.update_traces(textposition='inside')
fig.update_layout(uniformtext_minsize=12, uniformtext_mode='hide')

def newLegend(fig, newNames):
    for item in newNames:
        for i, elem in enumerate(fig.data[0].labels):
            if elem == item:
                fig.data[0].labels[i] = newNames[item]
    return(fig)

fig = newLegend(fig = fig, newNames = {'Australia':'Australia = Dangerous',
                                       'New Zealand' : 'New Zealand = Peaceful'})
fig.show()

编辑 1:来自 OP

的数据样本示例

您的数据面临的挑战是 genders 属于 integer 而不是 string。所以自定义函数试图用另一种类型的元素替换一种类型的元素。我通过一次替换包含标签的整个数组而不是逐个元素地操作它来解决这个问题。

剧情:

完整代码:

import pandas as pd
import plotly.express as px
import numpy as np

# custom function to change labels    
def newLegend(fig, newNames):
    newLabels = []
    for item in newNames:
        for i, elem in enumerate(fig.data[0].labels):
            if elem == item:
                #fig.data[0].labels[i] = newNames[item]
                newLabels.append(newNames[item])
    fig.data[0].labels = np.array(newLabels)
    return(fig)

'''
Pandas DataFrame:
'''
users_genders = pd.DataFrame({'0': {0: 1, 1: 2}, 
                              '802420': {0: 246049, 1: 106}})

users_genders = pd.DataFrame({'gender':[0,1,2],
                               'count_genders': [802420, 246049, 106]})

''' Pie Chart Viz '''
gender_distribution = px.pie(users_genders,
                             values='count_genders',
                             names='gender',
                             color_discrete_map={'0': 'blue',
                                                 '1': 'red',
                                                 '2': 'green'},
                             title='Gender Distribution <br>'
                                   'between 2006-02-16 to 2014-02-20',
                             hole=0.35)
gender_distribution.update_traces(textposition='outside',
                                  textinfo='percent+label',
                                  marker=dict(line=dict(color='#000000',
                                                        width=4)),
                                  pull=[0.05, 0, 0.03],
                                  opacity=0.9,
                                  # rotation=180
                                  )
gender_distribution.update_layout(legend=dict({'traceorder': 'normal'}
                                              # ticks='inside',
                                              # tickvals=[0, 1, 2],
                                              # ticktext=["0 - Female",
                                              #           "1 - Male",
                                              #           "2 - Undefined"],
                                              # dtick=3
                                              ),
                                   legend_title_text='User Genders')

# custom function set to work
gender_distribution=newLegend(gender_distribution, {0:"0 - Female",
                                                    1:"1 - Male",
                                                    2: "2 - Undefined"})


gender_distribution.show()