简体   繁体   English

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

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

I have a Pandas DataFrame, df which I am using to populate a Plotly bar chart.我有一个 Pandas DataFrame, df ,我用它来填充 Plotly 条形图。 For the sake of example, let's define df as the following:为了举例,让我们定义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]
    }
)

And create a bar chart derived from these data并创建从这些数据派生的条形图

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()

The bug arises in the hover text for the red stacked bar.该错误出现在红色堆叠条的 hover 文本中。 You'll notice that the x and y data in the hover text are correct, but the data arising from the customdata are not!您会注意到customdata文本中的xy数据是正确的,但自定义数据产生的数据不是!

颜色数据离散导致customdata乱序

Intriguingly, this error only occurs when the Pandas.Series object passed to the color argument of px.bar() consists of string data (ie discrete colour data).有趣的是,只有当传递给px.bar()color参数的Pandas.Series object 由字符串数据(即离散颜色数据)组成时,才会出现此错误。 If in the code above I instead set df.colour = [0, 0, 0, 1] (using integers for continuous colour data, notice the colorbar), the following graph is created:如果在上面的代码中我改为设置df.colour = [0, 0, 0, 1] (使用整数表示连续的颜色数据,请注意颜色条),则会创建以下图表:

连续颜色数据解决方法

My project requires the use of discrete colour data, is there a workaround for this bug?我的项目需要使用离散颜色数据,是否有解决此错误的方法?

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

and subsequently asked at https://github.com/plotly/plotly.py/issues/2716随后在https://github.com/plotly/plotly.py/issues/2716询问

It turns out the solution was relatively simple, and was my fault rather than being an issue with the source code itself (oh, the hubris of thinking that it wasn't my fault!)事实证明解决方案相对简单,是我的错而不是源代码本身的问题(哦,认为这不是我的错的狂妄自大!)

The reason my code breaks我的代码崩溃的原因

On running px.bar() , plotly.express creates a plotly.graph_objs.Figure object which contains two Bar objects, not one.在运行px.bar()时, plotly.express创建一个plotly.graph_objs.Figure 。图 object 包含两个Bar对象,而不是一个。 Then, when fig.update_traces() is called, the customdata is applied to all of the Bar objects which are children of fig .然后,当调用customdata fig.update_traces()时,自定义数据将应用于作为fig子对象的所有Bar对象。 Red Eric Idle is the 4th value of the original DataFrame, but fig.update_traces() doesn't care where Red Eric Idle used to be - it only understands that now it's part of a second Bar object. In fact, Red Eric Idle is the first datapoint of this Bar object, and so merrily assigns creates hovertext data using customdata[0][n] , customdata[1][n] , customdata[2][n] , with n=0 (the first value), rather than with n=3 (the fourth value) as I expected. 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 (第四个值)。

This is why the hover text for Red Eric Idle contains "a: 1, b: 1, c: 1" , rather than "a: 4, b: 16:, c: 64" .就是为什么 Red Eric Idle 的 hover 文本包含"a: 1, b: 1, c: 1" ,而不是"a: 4, b: 16:, c: 64"

The solution解决方案

The solution is very straightforward.解决方案非常简单。 Since the Plotly figure "forgets" where in the original DataFrame each point's data was supposed to go after it finishes running px.bar() , we simply have to assign custom data to each datapoint before it forgets (ie during the px.bar() call. Simply replace由于 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
)

with

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
)

Hey presto, Red Eric Idle suddenly has hover text with the 4, 16, 64 rather than 1, 1, 1 :嘿 presto,Red Eric Idle 突然有了 hover 文本,其中包含4, 16, 64而不是1, 1, 1

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

This is also neater code in the first place.首先,这也是更简洁的代码。 It wasn't obvious to me in the original Plotly example documentation that custom_data could be assigned like this within the plotly.express module.在原始的 Plotly 示例文档中,我并不明显可以在custom_data模块中像这样分配plotly.express

Why this didn't happen for continuous colour data为什么连续颜色数据没有发生这种情况

But why does this strange behaviour go away when we set df.colour = [0, 0, 0, 1] ?但是,当我们设置df.colour = [0, 0, 0, 1]时,为什么这种奇怪的行为 go 消失了?

The reason is that when px.bar() is passed continuous colour data, it only creates one Bar object per figure.原因是当px.bar()传入连续的颜色数据时,它只为每个图形创建一个Bar object。 In this case, every datapoint in Bar remembers its row position in the DataFrame, and so the assignment of customdata works like a charm.在这种情况下, Bar中的每个数据点都会记住其在 DataFrame 中的行customdata ,因此自定义数据的分配就像一个魅力。

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

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