Plotly-Express:如何在按列名设置颜色时修复颜色映射

Posted

技术标签:

【中文标题】Plotly-Express:如何在按列名设置颜色时修复颜色映射【英文标题】:Plotly-Express: How to fix the color mapping when setting color by column name 【发布时间】:2020-04-29 22:53:09 【问题描述】:

我使用plotly express 绘制散点图。标记的颜色由我的数据框的变量定义,如下例所示。

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

df = px.data.iris()

fig = px.scatter(df[df.species.isin(['virginica', 'setosa'])], x="sepal_width", y="sepal_length", color="species")
fig.show()

当我添加此变量的另一个实例时,颜色映射会发生变化(首先,'virginica' 是红色,然后是绿色)。

fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",size='petal_length', hover_data=['petal_width'])
fig.show()

添加变量时如何保持颜色的映射关系?

【问题讨论】:

【参考方案1】:

我找到了解决方案。函数px.scatter 有一个参数color_discrete_map,这正是我所需要的。 color_discrete_map 采用字典,其中键是物种的值,值是分配给物种的颜色。

import plotly.express as px    

df = px.data.iris()
color_discrete_map = 'virginica': 'rgb(255,0,0)', 'setosa': 'rgb(0,255,0)', 'versicolor': 'rgb(0,0,255)'
fig = px.scatter(df[df.species.isin(['virginica', 'setosa'])], x="sepal_width", y="sepal_length", color="species", color_discrete_map=color_discrete_map)
fig.show()

fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", color_discrete_map=color_discrete_map)
fig.show()

【讨论】:

第一个 sn-p 中的缩进对于最后三行似乎是错误的。 这应该是公认的答案,让别人的答案不是你自己的答案对你有好处,但几乎错过了这个答案,因为它低于零票答案。【参考方案2】:

简答:


1. 使用color_discrete_map 为变量分配颜色:

color_discrete_map = 'virginica': 'blue', 'setosa': 'red', 'versicolor': 'green'

或:

2. 管理数据的顺序以启用正确的颜色循环:

order_df(df_input = df, order_by='species', order=['virginica', 'setosa', 'versicolor'])

... 其中order_df 是一个处理长数据帧排序的函数,您可以在下面的代码 sn-ps 中找到完整的定义。


详情:


1.您可以直接map colors to variables:

color_discrete_map = 'virginica': 'blue', 'setosa': 'red', 'versicolor': 'green'

缺点是您必须指定变量名称和颜色。如果您正在使用变量数量不固定的数据框,那么这很快就会变得乏味。在这种情况下,关注default color sequence 或specify one to your liking 会更方便。所以我宁愿考虑管理您的数据集的顺序,以便您获得所需的颜色匹配。

2.真正挑战的来源:

px.Scatter() 将按照变量在数据框中出现的顺序为变量分配颜色。在这里,您使用了两个不同的来源dfdf[df.species.isin(['virginica', 'setosa', 'versicolor'])](我们将后者命名为df2)。运行df2['species'].unique() 会给你:

array(['setosa', 'virginica'], dtype=object)

运行df['species'] 会给你:

array(['setosa', 'versicolor', 'virginica'], dtype=object)

看到versicolor 在中间弹出了吗?这就是为什么red 不再分配给'virginica',而是'versicolor'

建议的解决方案:

因此,为了构建完整的解决方案,您必须找到一种方法来指定源数据框中变量的顺序。对于具有唯一值的列来说,这非常简单。对于像这样的长格式的数据帧来说,这需要更多的工作。您可以按照Changing row order in pandas dataframe without losing or messing up data 帖子中的说明进行操作。但在下面,我整理了一个非常简单的函数,它可以处理您想要使用 plotly express 绘制的数据帧的子集和顺序。

使用完整代码并在# data subsets 下的行之间切换将为您提供以下三个图:

情节 1: order=['virginica']

情节2: ['virginica', 'setosa']

情节3: order=['virginica', 'setosa', 'versicolor']

完整代码:

# imports
import pandas as pd
import plotly.express as px

# data
df = px.data.iris()

# function to subset and order a pandas
# dataframe fo a long format
def order_df(df_input, order_by, order):
    df_output=pd.DataFrame()
    for var in order:    
        df_append=df_input[df_input[order_by]==var].copy()
        df_output = pd.concat([df_output, df_append])
    return(df_output)

# data subsets
df_express = order_df(df_input = df, order_by='species', order=['virginica'])
df_express = order_df(df_input = df, order_by='species', order=['virginica', 'setosa'])
df_express = order_df(df_input = df, order_by='species', order=['virginica', 'setosa', 'versicolor'])

# plotly
fig = px.scatter(df_express, x="sepal_width", y="sepal_length", color="species")
fig.show()

【讨论】:

非常感谢您的回答!它肯定澄清了我的问题。但它本身并不是解决方案。 @otwtm 现在是。这与您的方法不同(这非常有用)。我的方法让您完全按照自己的意愿行事,而不必担心指定颜色。 非常感谢您提供完整的解决方案。如果不想自己指定颜色,这是一种很好的方法。万一想手动选择图形的颜色,我发现自己的解决方案更简洁。

以上是关于Plotly-Express:如何在按列名设置颜色时修复颜色映射的主要内容,如果未能解决你的问题,请参考以下文章

如何在按下另一个按钮之前更改按钮状态?

在按下时查看:按下时更改背景颜色?如何显示正在按下视图?

输入类型按钮在按下时会改变颜色?

使用 plotly-express 按值按降序排列条形图中的条形

VS C#编程 是WPF程序 如何改变ellipse控件的填充颜色 要在按下按钮1时为红色,按下按钮2变为绿色 求助?

ListItem 应在按下时更改背景颜色、文本和图像的颜色