我正在使用plotly express来绘制散点图。标记的颜色由我的dataframe的一个变量定义,如下面的示例所示。
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()

如何在添加变量时保持颜色的映射?
发布于 2020-01-13 22:43:38
简短的回答:
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是一个处理长数据帧排序的函数,您可以在下面的代码片段中找到完整的定义。
详细信息:
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()将按照变量在数据帧中出现的顺序将颜色分配给变量。这里您使用了两个不同的源df和df[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'的原因。
建议的解决方案:
因此,为了构建一个完整的解决方案,您必须找到一种方法来指定源数据帧中变量的顺序。对于具有唯一值的列来说,这是非常直接的。对于像这样的长格式的数据帧来说,这需要更多的工作。你可以按照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']

完整代码:
# 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()发布于 2020-01-14 16:06:44
我找到了一个解决方案。函数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()

https://stackoverflow.com/questions/59713016
复制相似问题