Plotly-Express:按列名设置颜色时如何修复颜色映射
Plotly-Express: How to fix the color mapping when setting color by column name
我正在使用 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. 为变量分配颜色 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'}
缺点是您必须指定变量名称和颜色。如果您使用的是变量数量不固定的数据帧,那么这很快就会变得乏味。在这种情况下,遵循 or 会方便得多。因此,我宁愿考虑管理数据集的顺序,以便获得所需的颜色匹配。
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 中的说明进行操作。但在下面,我整理了一个非常简单的函数,它可以处理您想使用 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()
我找到了解决办法。函数 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()
我正在使用 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. 为变量分配颜色 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'}
缺点是您必须指定变量名称和颜色。如果您使用的是变量数量不固定的数据帧,那么这很快就会变得乏味。在这种情况下,遵循
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
使用完整的代码并在 # 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()
我找到了解决办法。函数 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()