繁体   English   中英

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

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

我正在练习使用 Python 在 Plotly Express 中构建饼图。
所以,这是我制作的饼图;
在此处输入图像描述

此图表是从一个包含两列的文件构建的,称为

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

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

  • 0 - female
  • 1 - male
  • 2 - undefined

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

我当前对该图的代码:

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无济于事。 它返回有关不正确参数的错误消息。 有人会帮我解决这个问题吗?

编辑1 :如果我不清楚,我想知道是否可以修改图例中显示的值而不更改文件中的原始值。 非常感谢您抽出宝贵时间帮助我解决这个问题!

编辑 2 :添加代码的导入和其他先前的详细信息,删除 Dropbox 链接。

如果我正确理解您的问题,您希望更改图例中显示的内容而不更改数据源中的名称。 可能有更优雅的方法来做到这一点,但我已经将一个自定义函数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 的数据样本示例

您的数据面临的挑战是gendersinteger而不是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()
newnames = {'0': 'zero', '1': 'one', '2': 'two'}

fig.for_each_trace(lambda t: t.update(
  labels=[newnames[label] for label in t.labels]
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM