Plotly:如何在不更改数据源的情况下更改 go.pie 图表的图例? [英] Plotly: How to change legend for a go.pie chart without changing data source?

查看:185
本文介绍了Plotly:如何在不更改数据源的情况下更改 go.pie 图表的图例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am practising building a Pie Chart in Plotly Express using Python.
So, this is the Pie Chart that I made;

此图表是从一个名为

This chart was build from a file with two columns called

  1. gender 值为 [0, 1, 2]
  2. count_genders 的值为 [total_count_0, total_count_1, total_count_2]
  1. gender with values of [0, 1, 2]
  2. count_genders with values of [total_count_0, total_count_1, total_count_2]

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

I am planning to add some description to those values; for instance

  • 0 - 女性
  • 1 - 男性
  • 2 - 未定义

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

This is where I am currently stuck.
If I remember correctly if you want to change a label in the legend (at least in Choropleth map), you could manipulate the ticks located in colorscale bar. By manipulating them, you could rename the label about the data. Thus I am wondering if you could do the same in Pie chart?

我当前用于此图表的代码:

My current code for this graph:

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

I tried to add the ticks in the update_layout to no avail. It returns an error message about incorrect parameters. Would someone kindly help me fix this issue?

edit 1:如果我不清楚,我想知道是否可以在不更改文件中的原始值的情况下修改图例中显示的值.非常感谢您抽出宝贵时间来帮助我解决此问题!

edit 1: In case I wasn't clear, I wanted to know if it's possible to modify the values displayed in the legend without changing the original values within the file. Many thanks for your time for those who are already kind enough to help me fix this issue!

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

edit 2: Add the imports and other prior details of the code, removing the Dropbox link.

推荐答案

如果我正确理解您的问题,您希望更改图例中显示的内容而不更改数据源中的名称.可能有更优雅的方法来做到这一点,但我已经把一个自定义函数 newLegend(fig, newNames) 放在一起,它会为你做到这一点.

If I'm understanding your question correctly, you'd like to change what's displayed in the legend without changing the names in your data source. There may be more elegant ways of doing this but I've put together a custom function newLegend(fig, newNames) that will do exactly that for you.

这样的图:

...正在运行:

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

...会给你:

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

I hope this is what you were looking for. Don't hesitate to let me know if not!

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.所以自定义函数试图用另一种类型的元素替换一种类型的元素.我通过一次性替换包含标签的整个数组解决了这个问题,而不是逐个元素地操作它.

Edit 1: Example with data sample from OP

The challenge with your data was that genders were of type integer and not string. So the custom function tried to replace an element of one type with an element of another type. I've solved this by replacing the entire array containing your labels in one go instead of manipulating it element by element.

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()

这篇关于Plotly:如何在不更改数据源的情况下更改 go.pie 图表的图例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆