【问题标题】:Plotly Adding text to upper left of each subplot…(python)Plotly 在每个子图的左上角添加文本……(python)
【发布时间】:2021-07-25 09:52:37
【问题描述】:

我有一个财务图表,其中有一堆指标作为子图。与子图一起的主图可以显示多个时间序列。我想在每个子图中显示在该子图上绘制的任何系列的最后一个值,在左上角,类似于:

令人惊讶的是,事实证明这是相当困难的。虽然我可以找到在点/条上显示注释的文档,并且我可以在图的最左上角显示注释/文本,但似乎没有一种简单或直观的方法来简单地显示一些文本不绑定到 x 或 y 轴……在我的例子中,在左上角。

我所做的基本上是使用标题并尝试将其移动到每个子图的左上角。基本上,我首先为图表中的每个子图创建一个虚拟标题。然后稍后在 foreach 循环中迭代我的窗格对象列表时,这些对象基本上是元数据来告诉我如何绘制子图,当时我设置了标题的实际值并尝试重新定位到左侧:

    row_heights, titles =  zip(*[[x.rel_height, 'title'] for x in panes if x.rel_height is not None])

    self.fig = make_subplots(rows=len(self.panes), cols=1, shared_xaxes=True, 
            vertical_spacing=0.01, row_heights=row_heights, subplot_titles=titles)

    for i, p in enumerate(self.panes):
       ...
       self.fig.layout.annotations[i].update(text = p.info, x=0.025)
       *#self.fig.layout.annotations[i].update(text = p.info, x=0.025, y=1.0)*
       ...
    

上面的行会将标题很好地向左移动。但问题是,如果我尝试添加一个 y 值,则该 y 值基于整个图形,而不是相对于子图..所以所有文本都在一个位置结束。另一件事是,我不知道每个子图的实际高度以知道“顶部”可能是什么。

我们将不胜感激尝试解决此问题的任何帮助

【问题讨论】:

  • 您能否提供一个完整的可重现示例?

标签: python plotly


【解决方案1】:

注释子图的方式与 make_subpllots 相同,指定行和列。我根据公式中的reference 绘制了移动平均线、价格和交易量。注释可以从数据框中获取,但我单独创建了数据。我使用“域”作为每个图形的坐标来确定每个图形的位置。

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
last_volume = df["AAPL.Volume"][-1:]
last_price = ['{}:{:.2f}'.format(x, y) for x,y in zip(df.columns[1:5], df.iloc[-1, 1:5])]
last_price = ''.join(last_price)

fig = make_subplots(rows=3, cols=1, row_heights=[0.2, 0.6, 0.20], shared_xaxes=True, vertical_spacing=0.02)

fig.add_trace(go.Scatter(x=df['Date'], y=df['mavg'], name='mavg'), row=1, col=1)
fig.add_trace(go.Scatter(x=df['Date'], y=df['dn'], name='dn'), row=1, col=1)
fig.add_trace(go.Scatter(x=df['Date'], y=df['up'], name='up'), row=1, col=1)
fig.add_trace(go.Scatter(x=df['Date'], y=df['AAPL.High'], name='AAPL.High'), row=2, col=1)
fig.add_trace(go.Bar(x=df['Date'], y=df['AAPL.Volume'], name='AAPL.Volume'), row=3, col=1)

fig.update_layout(legend=dict(
    orientation="h",
    yanchor="bottom",
    y=1.02,
    xanchor="right",
    x=1
))

fig.update_yaxes(side='right')
fig.add_annotation(xref='x domain',
                   yref='y domain',
                   x=0.01,
                   y=0.9,
                   text='Volume:' + str(last_volume.values), 
                   showarrow=False,
                   row=3, col=1)

fig.add_annotation(xref='x domain',
                   yref='y domain',
                   x=0.01,
                   y=0.99,
                   text='Price:' + str(last_price), 
                   showarrow=False,
                   row=2, col=1)


fig.update_layout(title_text='<b>AAPL Stock Cart</b>')
fig.show()

【讨论】:

  • 这太棒了..我想出了一些接近的东西,但是缺少正确的外部参照、yref 和 id 组合,而不是使用行、列值。问题:我知道我可以添加 l/r/t/b 边距和填充,但我可以为每个子图只做顶部填充吗?
  • 如果使用图形间距,例如row_heights=[0.15,0.6,0.15],就会得到间距。您还可以通过设置 vertical_spacing=0.6 来增加间距。我认为您也可以使用 t 在顶部图表中设置差距。
  • 谢谢。 row_heights 将控制每个“窗格”的高度。垂直间距控制窗格之间的空间。我要做的是在每个窗格的顶部创建一个区域,可以在其中编写描述/文本以及线条不会覆盖的位置。
  • 你试过调整行高和水平间距吗?在三个图中,[0.15,0.6,0.15] 表示 15%、60%、15%,小于 100 的 5% 应用于空间。小于 100 的 5% 应用于空白。我想你可以打算在那里注释。
猜你喜欢
  • 2021-09-20
  • 2019-01-06
  • 2023-01-20
  • 2021-12-24
  • 2021-03-13
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多