繁体   English   中英

Plotly.py 在堆叠条形图上使用离散颜色数据的错误,自定义数据在 hover 文本中

[英]Plotly.py bug using discrete colour data on stacked bar chart with customdata in hover text

我有一个 Pandas DataFrame, df ,我用它来填充 Plotly 条形图。 为了举例,让我们定义df如下:

import pandas, numpy
import plotly.express as px

df = pandas.DataFrame.from_dict(
    {
        "x": ["John Cleese", "Eric Idle", "Michael Palin", "Eric Idle"],
        "y": [7, 10, 3, 8],
        "colour": ["0", "0", "0", "1"],
        "a": [1, 2, 3, 4],
        "b": [1, 4, 9, 16],
        "c": [1, 8, 27, 64]
    }
)

并创建从这些数据派生的条形图

fig = px.bar(df, x="x", y="y", color="colour", barmode="stack")

my_customdata = numpy.transpose(numpy.array([df["a"], df["b"], df["c"]]))

fig = fig.update_traces(
    patch={
        "customdata": my_customdata,
        "hovertemplate": "x: %{x}, y: %{y}, a: %{customdata[0]}, b: %{customdata[1]}, c: %{customdata[2]}<extra></extra>"
    },
    overwrite=True
)
fig.update_layout(
    xaxis={"categoryorder": "total ascending"}
)
fig.show()

该错误出现在红色堆叠条的 hover 文本中。 您会注意到customdata文本中的xy数据是正确的,但自定义数据产生的数据不是!

颜色数据离散导致customdata乱序

有趣的是,只有当传递给px.bar()color参数的Pandas.Series object 由字符串数据(即离散颜色数据)组成时,才会出现此错误。 如果在上面的代码中我改为设置df.colour = [0, 0, 0, 1] (使用整数表示连续的颜色数据,请注意颜色条),则会创建以下图表:

连续颜色数据解决方法

我的项目需要使用离散颜色数据,是否有解决此错误的方法?

最初在https://community.plotly.com/t/bug-using-bar-chart-categoryorder-and-customdata/43925?fbclid=IwAR2yKnSgedDjDmIGe3vhd8GPiQ_DFFAGehrq6G4Wl80iJST3Psn6kkzIs8 询问

随后在https://github.com/plotly/plotly.py/issues/2716询问

事实证明解决方案相对简单,是我的错而不是源代码本身的问题(哦,认为这不是我的错的狂妄自大!)

我的代码崩溃的原因

在运行px.bar()时, plotly.express创建一个plotly.graph_objs.Figure 。图 object 包含两个Bar对象,而不是一个。 然后,当调用customdata fig.update_traces()时,自定义数据将应用于作为fig子对象的所有Bar对象。 Red Eric Idle 是原始 DataFrame 的第 4 个值,但是fig.update_traces()不关心 Red Eric Idle曾经在哪里 - 它只知道现在它是第二个Bar object 的一部分。事实上,Red Eric Idle 是此Bar的第一个数据点 object,因此愉快地使用customdata[0][n]customdata[1][n]customdata[2][n]创建悬停文本数据,其中n=0 (第一个值),而不是像我预期的那样使用n=3 (第四个值)。

就是为什么 Red Eric Idle 的 hover 文本包含"a: 1, b: 1, c: 1" ,而不是"a: 4, b: 16:, c: 64"

解决方案

解决方案非常简单。 由于 Plotly 图在完成运行px.bar()后“忘记”了原始 DataFrame 中每个点的数据应该为 go 的位置,我们只需在每个数据点忘记之前(即在px.bar()电话. 只需更换

fig = px.bar(df, x="x", y="y", color="colour", barmode="stack")
my_customdata = numpy.transpose(numpy.array([df["a"], df["b"], df["c"]]))
fig = fig.update_traces(
    patch={
        "customdata": my_customdata,
        "hovertemplate": "x: %{x}, y: %{y}, a: %{customdata[0]}, b: %{customdata[1]}, c: %{customdata[2]}<extra></extra>"
    },
    overwrite=True
)

fig = px.bar(
    df, x="x", y="y", color="colour", barmode="stack", custom_data=["a", "b", "c"]
)
fig = fig.update_traces(
    patch={
        "hovertemplate": "x: %{x}, y: %{y}, a: %{customdata[0]}, b: %{customdata[1]}, c: %{customdata[2]}"
    },
    overwrite=True
)

嘿 presto,Red Eric Idle 突然有了 hover 文本,其中包含4, 16, 64而不是1, 1, 1

预期的悬停文本行为已恢复

首先,这也是更简洁的代码。 在原始的 Plotly 示例文档中,我并不明显可以在custom_data模块中像这样分配plotly.express

为什么连续颜色数据没有发生这种情况

但是,当我们设置df.colour = [0, 0, 0, 1]时,为什么这种奇怪的行为 go 消失了?

原因是当px.bar()传入连续的颜色数据时,它只为每个图形创建一个Bar object。 在这种情况下, Bar中的每个数据点都会记住其在 DataFrame 中的行customdata ,因此自定义数据的分配就像一个魅力。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM