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

otw*_*wtm 4 python plotly plotly-express

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

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

在此处输入图片说明

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

otw*_*wtm 11

我找到了解决方案。该函数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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", color_discrete_map=color_discrete_map)
fig.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


ves*_*and 9


简短回答:


1.使用以下命令为变量分配颜色color_discrete_map

color_discrete_map = {'virginica': 'blue', 'setosa': 'red', 'versicolor': 'green'}
Run Code Online (Sandbox Code Playgroud)

或者:

2.通过以下方式管理数据顺序以实现正确的颜色循环:

order_df(df_input = df, order_by='species', order=['virginica', 'setosa', 'versicolor'])
Run Code Online (Sandbox Code Playgroud)

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


细节:


1. 您可以直接将颜色映射到变量:

color_discrete_map = {'virginica': 'blue', 'setosa': 'red', 'versicolor': 'green'}
Run Code Online (Sandbox Code Playgroud)

缺点是您必须指定变量名称和颜色。如果您使用变量数量不固定的数据框,这很快就会变得乏味。在这种情况下,遵循默认颜色顺序指定您喜欢的颜色顺序会更方便。因此,我宁愿考虑管理数据集的顺序,以便您获得所需的颜色匹配。

2. 真正挑战的来源:

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

array(['setosa', 'virginica'], dtype=object)
Run Code Online (Sandbox Code Playgroud)

跑步df['species']会给你带来:

array(['setosa', 'versicolor', 'virginica'], dtype=object)
Run Code Online (Sandbox Code Playgroud)

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

建议的解决方案:

因此,为了构建完整的解决方案,您必须找到一种方法来指定源数据框中变量的顺序。对于具有独特值的专栏来说,这是非常简单的。对于像这样的长格式数据帧来说,需要做更多的工作。您可以按照更改 pandas dataframe 中的行顺序帖子中的描述进行操作,而不会丢失或弄乱数据。但下面我整理了一个非常简单的函数,它可以处理您想要用plotlyexpress绘制的数据帧的子集和顺序。

使用完整的代码并在下面的行之间切换# 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()
Run Code Online (Sandbox Code Playgroud)