【问题标题】:Plotly: How to define colors in a figure using plotly.graph_objects and plotly.express?Plotly:如何使用 plotly.graph_objects 和 plotly.express 定义图形中的颜色?
【发布时间】:2026-01-16 07:15:02
【问题描述】:

有许多问题和答案以某种方式触及这个主题。有了这个贡献,我想清楚地说明为什么像marker = {'color' : 'red'} 这样的简单方法适用于plotly.graph_objects (go),但color='red' 不适用于plotly.express (px),尽管颜色是px.Linepx.Scatter 的属性. 而且我想证明为什么它没有那么棒。


那么,如果 px 应该是 easiest way to make a plotly figure,那么为什么像 color='red' 这样明显的事情会返回错误

ValueError: 'color' 的值不是 'data_frame' 中列的名称。

简而言之,这是因为px 中的color 不接受任意颜色名称或代码,而是数据集中的变量名称,以便将color cycle 分配给唯一值并将它们显示为不同颜色的线条。

让我通过应用gapminder 数据集来演示,并显示截至2007 的全球所有(至少大多数)国家/地区的Life expectancyGDP per capita 的散点图。像下面这样的基本设置将产生以下情节

图 1,使用go 绘制:

颜色由名为plotly 的循环设置,但此处使用 marker = {'color' : 'red'} 指定

图2,代码:

import plotly.graph_objects as go

df = px.data.gapminder()
df=df.query("year==2007")

fig = go.Figure()
fig.add_traces(go.Scatter(x=df['gdpPercap'], y=df["lifeExp"],
                          mode = 'markers',
                          marker = {'color' : 'red'}
                         ))
fig.show()

所以让我们用px 试试这个,并假设color='red' 可以解决问题:

代码 2,尝试使用 px 定义颜色的散点图:

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

# dataframe
df = px.data.gapminder()
df=df.query("year==2007")

# plotly express scatter plot
px.scatter(df, x="gdpPercap", y="lifeExp",
           color = 'red',
          )

结果:

ValueError: 'color' 的值不是列的名称 “数据帧”。期望 ['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap', 'iso_alpha', 'iso_num'] 但收到: 红色

那么这里发生了什么?

【问题讨论】:

    标签: python colors plotly plotly-python


    【解决方案1】:

    首先,如果需要对gopx 之间更广泛的区别进行解释,请查看herehere。如果完全不需要解释,你会在答案的最后找到一个完整的代码 sn-p,它将揭示 plotly.express 中的许多颜色的力量


    第 1 部分:本质:

    一开始可能不是这样,但有非常充分的理由说明color='red' 不能像您使用px 所期望的那样工作。但首先,如果您只想使用manually set a particular color for all markers,您可以使用.update_traces(marker=dict(color='red')),感谢pythons chaining method。但首先,让我们看看默认设置:

    1.1 Plotly 表达默认值

    图1,px默认散点图使用px.Scatter

    代码1,像素默认散点图使用px.Scatter

    # imports
    import plotly.express as px
    import pandas as pd
    
    # dataframe
    df = px.data.gapminder()
    df=df.query("year==2007")
    
    # plotly express scatter plot
    px.scatter(df, x="gdpPercap", y="lifeExp")
    

    这里,正如问题中已经提到的,颜色被设置为默认情节序列中的第一种颜色,可通过px.colors.qualitative.Plotly 获得:

    ['#636EFA', # the plotly blue you can see above
     '#EF553B',
     '#00CC96',
     '#AB63FA',
     '#FFA15A',
     '#19D3F3',
     '#FF6692',
     '#B6E880',
     '#FF97FF',
     '#FECB52']
    

    这看起来很不错。但是,如果您想同时更改内容甚至添加更多信息怎么办?

    1.2:如何覆盖默认值并完全使用 px 颜色执行您想要的操作:

    正如我们已经提到的px.scattercolor 属性不会像red 这样的颜色作为参数。相反,您可以例如使用color='continent' 轻松区分数据集中的不同变量。但是px 中的颜色还有很多:


    以下六种方法的组合将让您完全使用 plotly express 来完成您想要的颜色。请记住,您甚至不必选择。您可以同时使用以下方法中的onesomeall。一种特别有用的方法将显示为13 的组合。但我们稍后会谈到这一点。这是你需要知道的:

    1. 改变px使用的颜色顺序:

    color_discrete_sequence=px.colors.qualitative.Alphabet
    

    2. 使用 color 参数

    将不同的颜色分配给不同的变量
    color = 'continent'
    

    3. 使用

    自定义一种或多种可变颜色
    color_discrete_map={"Asia": 'red'}
    

    4. 使用 dict comprehension 和 color_discrete_map

    轻松对较大的变量子集进行分组
    subset = {"Asia", "Africa", "Oceania"}
    group_color = {i: 'red' for i in subset}
    

    5. 使用rgba()颜色代码设置不透明度。

    color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}
    

    6. 覆盖所有设置:

    .update_traces(marker=dict(color='red'))
    

    第 2 部分:细节和情节

    以下 sn-p 将生成下图,显示所有大陆在不同 GDP 水平下的预期寿命。标记的大小代表不同级别的人口,从一开始就让事情变得更有趣。

    情节2:

    代码2:

    import plotly.express as px
    import pandas as pd
    
    # dataframe, input
    df = px.data.gapminder()
    df=df.query("year==2007")
    
    px.scatter(df, x="gdpPercap", y="lifeExp",
               color = 'continent',
               size='pop',
              )
    

    为了说明上述方法的灵活性,我们首先更改颜色顺序。由于我们对于初学者只显示 one 类别和 one 颜色,因此您必须等待后续步骤才能看到实际效果。但这里是与color_discrete_sequence=px.colors.qualitative.Alphabet 相同的情节,按照第 1 步:

    1.

    改变px使用的颜色顺序
    color_discrete_sequence=px.colors.qualitative.Alphabet
    

    现在,让我们将Alphabet 颜色序列中的颜色应用到不同的大陆:

    2. 使用 color 参数

    为不同的变量分配不同的颜色
    color = 'continent'
    

    如果您像我一样认为这种特定的颜色序列很容易看,但可能有点难以区分,您可以将您选择的颜色分配给一个或多个大洲,如下所示:

    3. 使用

    自定义一种或多种可变颜色
    color_discrete_map={"Asia": 'red'}
    

    这非常棒:现在您可以更改序列并为特别有趣的变量选择任何您喜欢的颜色。但是,如果您想将特定颜色分配给更大的子集,上述方法可能会有点乏味。因此,您也可以使用dict comprehension 来做到这一点:

    4. 使用字典理解和color_discrete_map为组分配颜色

    # imports
    import plotly.express as px
    import pandas as pd
    
    # dataframe
    df = px.data.gapminder()
    df=df.query("year==2007")
    
    subset = {"Asia", "Europe", "Oceania"}
    group_color = {i: 'red' for i in subset}
    
    # plotly express scatter plot
    px.scatter(df, x="gdpPercap", y="lifeExp",
               size='pop',
               color='continent',
               color_discrete_sequence=px.colors.qualitative.Alphabet,
               color_discrete_map=group_color
              )
    

    5. 使用rgba() 颜色代码设置不透明度。

    现在让我们后退一步。如果您认为 red 非常适合亚洲,但可能有点过于强烈,您可以使用 rgba 颜色调整不透明度,例如 'rgba(255,0,0,0.4)' 来获得:

    最后一张图的完整代码:

    import plotly.express as px
    import pandas as pd
    
    # dataframe, input
    df = px.data.gapminder()
    df=df.query("year==2007")
    
    px.scatter(df, x="gdpPercap", y="lifeExp",
               color_discrete_sequence=px.colors.qualitative.Alphabet,
               color = 'continent',
               size='pop',
               color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}
              )
    

    如果您认为我们现在变得有点过于复杂,您可以再次覆盖所有设置:

    6. 覆盖所有设置:

    .update_traces(marker=dict(color='red'))
    

    这让我们回到了开始的地方。我希望你会发现这很有用!

    包含所有可用选项的完整代码 sn-p:

    # imports
    import plotly.express as px
    import pandas as pd
    
    # dataframe
    df = px.data.gapminder()
    df=df.query("year==2007")
    
    subset = {"Asia", "Europe", "Oceania"}
    group_color = {i: 'red' for i in subset}
    
    # plotly express scatter plot
    px.scatter(df, x="gdpPercap", y="lifeExp",
               size='pop',
               color='continent',
               color_discrete_sequence=px.colors.qualitative.Alphabet,
               #color_discrete_map=group_color
               color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}
              )#.update_traces(marker=dict(color='red'))
    

    【讨论】:

    • 绝妙的答案!
    • @Dr.H.Lecter 很高兴你喜欢它!出于好奇,是什么特别的挑战让您寻找它?和问题中描述的完全一样吗?还是有点不同?
    • “如何覆盖默认值并使用 px 颜色完全按照您的要求执行操作”的更大问题/答案,我无法轻松或快速地找到我在文档中寻找的信息。
    • @Dr.H.Lecter 感谢您的反馈!我实际上会考虑将标题更改为“如何覆盖默认值并使用 px 颜色执行您想要的操作”。