首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Plotly-Express:如何在按列名设置颜色时修复颜色映射

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

Stack Overflow用户
提问于 2020-01-13 16:36:58
回答 2查看 13.4K关注 0票数 5

我正在使用plotly express来绘制散点图。标记的颜色由我的dataframe的一个变量定义,如下面的示例所示。

代码语言:javascript
复制
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',是红色,然后是绿色)。

代码语言:javascript
复制
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",size='petal_length', hover_data=['petal_width'])
fig.show()

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-13 22:43:38

简短的回答:

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

代码语言:javascript
复制
color_discrete_map = {'virginica': 'blue', 'setosa': 'red', 'versicolor': 'green'}

或者:

2.使用以下功能管理数据的顺序,以启用正确的颜色循环:

代码语言:javascript
复制
order_df(df_input = df, order_by='species', order=['virginica', 'setosa', 'versicolor'])

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

详细信息:

1.您可以直接使用map colors to variables

代码语言:javascript
复制
color_discrete_map = {'virginica': 'blue', 'setosa': 'red', 'versicolor': 'green'}

缺点是您必须指定变量名称和颜色。如果您正在处理变量数量不固定的数据帧,这很快就会变得单调乏味。在这种情况下,遵循default color sequencespecify one to your liking会方便得多。因此,我更愿意考虑使用来管理数据集的顺序,这样您就可以获得所需的颜色匹配。

2.真正挑战的来源:

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

代码语言:javascript
复制
array(['setosa', 'virginica'], dtype=object)

运行df['species']将为您带来以下好处:

代码语言:javascript
复制
array(['setosa', 'versicolor', 'virginica'], dtype=object)

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

建议的解决方案:

因此,为了构建一个完整的解决方案,您必须找到一种方法来指定源数据帧中变量的顺序。对于具有唯一值的列来说,这是非常直接的。对于像这样的长格式的数据帧来说,这需要更多的工作。你可以按照post Changing row order in pandas dataframe without losing or messing up data中的描述来做。但在下面,我已经组合了一个非常简单的函数,它既可以处理数据帧的子集,也可以处理要绘制的数据帧的顺序。

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

图1: order=['virginica']

图2: ['virginica', 'setosa']

图3: order=['virginica', 'setosa', 'versicolor']

完整代码:

代码语言:javascript
复制
# 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()
票数 5
EN

Stack Overflow用户

发布于 2020-01-14 16:06:44

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

代码语言:javascript
复制
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()

代码语言:javascript
复制
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", color_discrete_map=color_discrete_map)
fig.show()

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59713016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档