Plotly:如何在 plotly express 折线图中更改图例的变量/标签名称?

Posted

技术标签:

【中文标题】Plotly:如何在 plotly express 折线图中更改图例的变量/标签名称?【英文标题】:Plotly: How to change variable/label names for the legend in a plotly express line chart? 【发布时间】:2021-01-29 21:56:35 【问题描述】:

我想在 python 中更改 plotly express 中的变量/标签名称。我首先创建一个情节:

import pandas as pd
import plotly.express as px

d = 'col1': [1, 2, 3], 'col2': [3, 4, 5]
df = pd.DataFrame(data=d)
fig = px.line(df, x=df.index, y=['col1', 'col2'])
fig.show()

产量:

我想将标签名称从 col1 更改为 hello 并从 col2 更改为 hi。我试过在图中使用标签,但我无法让它工作:

fig = px.line(df, x=df.index, y=['col1', 'col2'], labels='col1': "hello", 'col2': "hi")
fig.show()

但这似乎什么也没做,同时不会产生错误。显然,我可以通过更改列名来实现我的目标,但我尝试创建的实际绘图并不允许这样做,因为它来自几个不同的数据框。

【问题讨论】:

很好的答案,它完成了工作。我希望您构建的功能已经是 plotly express 模块的一部分,但是我从您的回答中了解到情况并非如此? 【参考方案1】:

答案:

在不更改数据源的情况下,完全替换图例、图例组和悬停模板中的名称将需要:

newnames = 'col1':'hello', 'col2': 'hi'
fig.for_each_trace(lambda t: t.update(name = newnames[t.name],
                                      legendgroup = newnames[t.name],
                                      hovertemplate = t.hovertemplate.replace(t.name, newnames[t.name])
                                     )
                  )

剧情:

详情:

使用

fig.for_each_trace(lambda t: t.update(name = newnames[t.name]))

...您可以更改图例中的名称,而无需使用 dict 更改源

newnames = 'col1':'hello', 'col2': 'hi'

...并将新名称映射到图形结构以下部分中的现有 col1col2(对于您的第一个跟踪,col1):

'hovertemplate': 'variable=col1<br>index=%x<br>value=%y<extra></extra>',
'legendgroup': 'col1',
'line': 'color': '#636efa', 'dash': 'solid',
'mode': 'lines',
'name': 'hello',   # <============================= here!
'orientation': 'v',
'showlegend': True,
'type': 'scatter',
'x': array([0, 1, 2], dtype=int64),
'xaxis': 'x',
'y': array([1, 2, 3], dtype=int64),
'yaxis': 'y',

但正如您所见,这对'legendgroup': 'col1''hovertemplate': 'variable=col1&lt;br&gt;index=%x&lt;br&gt;value=%y&lt;extra&gt;&lt;/extra&gt;' 没有任何作用,并且根据您的图形的复杂性,这可能会造成问题。所以我会添加 legendgroup = newnames[t.name]hovertemplate = t.hovertemplate.replace(t.name, newnames[t.name])

完整代码:

import pandas as pd
import plotly.express as px
from itertools import cycle

d = 'col1': [1, 2, 3], 'col2': [3, 4, 5]
df = pd.DataFrame(data=d)
fig = px.line(df, x=df.index, y=['col1', 'col2'])

newnames = 'col1':'hello', 'col2': 'hi'
fig.for_each_trace(lambda t: t.update(name = newnames[t.name],
                                      legendgroup = newnames[t.name],
                                      hovertemplate = t.hovertemplate.replace(t.name, newnames[t.name])
                                     )
                  )

【讨论】:

感谢您的解决方案,它适用于图例本身中的名称。将鼠标移到曲线上时,框中显示的名称仍然是旧名称而不是新名称。知道如何解决这个问题吗? 这里是解决方案,函数customLegend需要扩展如下: def customLegendPlotly(fig, nameSwap): for i, dat in enumerate(fig.data): for elem in dat:如果 elem == 'hovertemplate': fig.data[i].hovertemplate = fig.data[i].hovertemplate.replace(fig.data[i].name, nameSwap[fig.data[i].name]) 为elem in dat: if elem == 'name': fig.data[i].name = nameSwap[fig.data[i].name] return fig【参考方案2】:

添加“名称”参数:go.Scatter(name=...)

来源https://plotly.com/python/figure-labels/

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5, 6, 7, 8],
    y=[0, 1, 2, 3, 4, 5, 6, 7, 8],
    name="Name of Trace 1"       # this sets its legend entry
))


fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5, 6, 7, 8],
    y=[1, 0, 3, 2, 5, 4, 7, 6, 8],
    name="Name of Trace 2"
))

fig.update_layout(
    title="Plot Title",
    xaxis_title="X Axis Title",
    yaxis_title="X Axis Title",
    legend_title="Legend Title",
    font=dict(
        family="Courier New, monospace",
        size=18,
        color="RebeccaPurple"
    )
)

fig.show()

【讨论】:

是的,但是此解决方案仅适用于使用 plotly.graph_objects 创建的图形,而 OP 的查询与 plotly.express 有关【参考方案3】:

这段代码更简洁。

import pandas as pd
import plotly.express as px

df = pd.DataFrame(data='col1': [1, 2, 3], 'col2': [3, 4, 5])

series_names = ["hello", "hi"]

fig = px.line(data_frame=df)

for idx, name in enumerate(series_names):
    fig.data[idx].name = name
    fig.data[idx].hovertemplate = name

fig.show()

【讨论】:

【参考方案4】:

如果你正在寻找更简洁的东西,这个函数就可以了-

def custom_legend_name(new_names):
    for i, new_name in enumerate(new_names):
        fig.data[i].name = new_name

然后在fig.show() 之前,只需将一个包含您想要的名称的列表传递给函数,就像这样custom_legend_name(['hello', 'hi'])

这是完整代码的样子-

def custom_legend_name(new_names):
    for i, new_name in enumerate(new_names):
        fig.data[i].name = new_name
        

import pandas as pd
import plotly.express as px

d = 'col1': [1, 2, 3], 'col2': [3, 4, 5]
df = pd.DataFrame(data=d)
fig = px.line(df, x=df.index, y=['col1', 'col2'])
custom_legend_name(['hello','hi'])
fig.show()

【讨论】:

以上是关于Plotly:如何在 plotly express 折线图中更改图例的变量/标签名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Plotly Express 和 Plotly 隐藏图例

Plotly:如何在 plotly express 折线图中更改图例的变量/标签名称?

Plotly:使用 plotly express 行时如何在 hoverinfo 中格式化日期?

Plotly:如何手动设置 plotly express 散点图中点的颜色?

Plotly:如何使用 plotly express 自定义 xaxis 刻度标签?

Plotly:如何重命名 plotly express 堆积条形图的图例元素?