plotly / plotly/plotly.py

add_vline/hline annotation text location fixed to first shape if using a pre-instantiated dict for the "annotation" input parameter

未关闭
#3,547 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

bug P3
主要语言
Python
星标
18.8k
派生
2.8k
平均合并
16 小时 26 分钟
30 天内合并 PR
21

描述

Hi

When I instantiate a dict once with some constant formatting that I want to pass to the "annotation" argument for several calls of .add_vline() (or .add_hline()), all annotations for shapes created with this dict are placed with the shape created by the initial .add_vline() call.

e.g.:

import plotly.graph_objects as go

fig = go.Figure()

y_1 = [3000, 3500, 4000, 3500, 3000, 3500]
x_1 = list(range(len(y_1)))
fig.add_trace(go.Scatter(x=x_1, y=y_1))


annotation = dict(font_color="#000000")

fig.add_vline(x=2, annotation_text="vline 1", annotation=annotation)

print(f"annotation after first .add_vline():\n{annotation}")

fig.add_vline(x=3, annotation_text="vline 2", annotation=annotation)

print(f"annotation after second .add_vline():\n{annotation}")


fig.write_html("graph.html")

produces graph and output (similar result if .add_hline() used instead) - expected graph can be seen at the end of this post:
image

annotation after first .add_vline():
{'font_color': '#000000', 'text': 'vline 1', 'xanchor': 'left', 'yanchor': 'top', 'x': 2, 'y': 1, 'showarrow': False}
annotation after second .add_vline():
{'font_color': '#000000', 'text': 'vline 2', 'xanchor': 'left', 'yanchor': 'top', 'x': 2, 'y': 1, 'showarrow': False}

Is this expected behaviour? As the x coordinate is explicitly given in the method I would expect that the annotation defined would be placed at that x, as happens with the different annotation_text values.

As we can see from the output, it is because the original annotation dictionary instance is being mutated in the process of adding the annotation. Then if an x value is present in the annotation dictionary, it is not overwritten, but the text value is if a new annotation_text value is passed.

Looking at the package code, I can achieve the behaviour I expected by implementing an else here:
https://github.com/plotly/plotly.py/blob/cfad7862594b35965c0e000813bd7805e8494a5b/packages/python/plotly/plotly/shapeannotation.py#L203-L204
Suggestion:

    if annotation is None:
        annotation = dict()
    else:
        annotation = annotation.copy()

I have made this change locally and run fine and as I expect.

If the current behaviour is not the expected behaviour, and if the suggested change above is acceptable, I would be glad to implement and test it appropriately then submit a pull request.

Cheers!


Graph I expect:
image

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 plotly/shapeannotation.py 的第 203-204 行开始,使用同一个 annotation dictionary 重复调用 add_vline() 来复现该问题,然后与 add_hline() 进行比较。完成的标准是:提供的 dictionary 不被修改,并且每个 shape 的 annotation 使用各自的坐标;根据需要为这两个方法添加或更新测试。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
data-visualization
Issue 类型
缺陷
难度
2/5
预计耗时
1-3 小时
活跃度
停滞
描述清晰度
描述清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。