Plotly:如何添加多个 y 轴?

Ves*_*per 8 python python-3.x plotly

我有 5 个不同列的数据,它们的值彼此不同。

Actual gen  Storage Solar Gen   Total Gen   Frequency
  1464      1838    1804         18266        51 
  2330      2262    518          4900         51
  2195      923     919          8732         49
  2036      1249    1316         3438         48
  2910      534     1212         4271         47
  857       2452    1272         6466         50
  2331      990     2729         14083        51
  2604      767     2730         19037        47
  993       2606    705          17314        51
  2542      213     548          10584        52
  2030      942     304          11578        52
  562       414     2870         840          52
  1111      1323    337          19612        49   
  1863      2498    1992         18941        48
  1575      2262    1576         3322         48
  1223      657     661          10292        47
  1850      1920    2986         10130        48
  2786      1119    933          2680         52
  2333      1245    1909         14116        48
  1606      2934    1547         13767        51
Run Code Online (Sandbox Code Playgroud)

因此,我想根据这些数据绘制一个具有 3 个 y 轴的图表。第一个用于frequency,第二个用于Total Gen,第三个用于Actual genStorageSolar Gen。频率应位于辅助 Y 轴(右侧),其余部分应位于左侧。

  • 对于频率,您可以看到这些值在 47 到 52 之间非常随机,这就是为什么它应该位于右侧,如下所示: 在此输入图像描述

  • 因为总 Gen 值与其他值相比非常高,因为它们在 100-20000 之间,所以我无法将它们与其他值合并,如下所示: 在此输入图像描述 在这里我想要:

  • Y 轴标题 1 = 实际发电、存储和太阳能发电

  • Y 轴标题 2 = 总生成数

  • Y 轴标题 3 = 频率

我的做法:

import logging

import pandas as pd
import plotly.graph_objs as go
import plotly.offline as pyo
import xlwings as xw
from plotly.subplots import make_subplots

app = xw.App(visible=False)
try:
    wb = app.books.open('2020 10 08 0000 (Float).xlsx')
    sheet = wb.sheets[0]
    
    actual_gen = sheet.range('A2:A21').value
    frequency = sheet.range('E2:E21').value
    storage = sheet.range('B2:B21').value
    total_gen = sheet.range('D2:D21').value
    solar_gen = sheet.range('C2:C21').value

except Exception as e:
    logging.exception("Something awful happened!")
    print(e)
finally:
    app.quit()
    app.kill()

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Add traces
fig.add_trace(
    go.Scatter(y=storage, name="BESS(KW)"),
)
fig.add_trace(
    go.Scatter(y=actual_gen, name="Act(KW)"),
)
fig.add_trace(
    go.Scatter(y=solar_gen, name="Solar Gen")
)
fig.add_trace(
    go.Scatter(x=x_values, y=total_gen, name="Total Gen",yaxis = 'y2')
)
fig.add_trace(
    go.Scatter(y=frequency, name="Frequency",yaxis = 'y1'),
)

fig.update_layout( title_text = '8th oct BESS',
    yaxis2=dict(title="BESS(KW)",titlefont=dict(color="red"), tickfont=dict(color="red")),
    yaxis3=dict(title="Actual Gen(KW)",titlefont=dict(color="orange"),tickfont=dict(color="orange"), anchor="free", overlaying="y2", side="left"),
    yaxis4=dict(title="Solar Gen(KW)",titlefont=dict(color="pink"),tickfont=dict(color="pink"), anchor="x2",overlaying="y2", side="left"),
    yaxis5=dict(title="Total Gen(KW)",titlefont=dict(color="cyan"),tickfont=dict(color="cyan"), anchor="free",overlaying="y2", side="left"),
    yaxis6=dict(title="Frequency",titlefont=dict(color="purple"),tickfont=dict(color="purple"), anchor="free",overlaying="y2", side="right"))

fig.show()
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?

S3D*_*DEV 7

以下是如何创建多级 y 轴的示例。

本质上,关键是:

  • 在字典中为每个轴创建一个键layout,然后为该轴分配一条跟踪。
  • 将 设定xaxis domain为比 更窄[0, 1](例如[0.2, 1]),从而将图形的左边缘向右推,为多级 y 轴腾出空间。

有关该主题的官方 Plotly 文档的链接。

为了使本演示更容易读取数据,我将数据集存储为 CSV 文件,而不是 Excel - 然后使用该函数将pandas.read_csv()数据集加载到 中pandas.DataFrame,然后将其作为数据列传递到绘图函数中。

例子:

读取数据集:

df = pd.read_csv('energy.csv')
Run Code Online (Sandbox Code Playgroud)

示例绘图代码:

import plotly.io as pio

layout = {'title': '8th Oct BESS'}
traces = []

traces.append({'y': df['storage'], 'name': 'Storage'})
traces.append({'y': df['actual_gen'], 'name': 'Actual Gen'})
traces.append({'y': df['solar_gen'], 'name': 'Solar Gen'})
traces.append({'y': df['total_gen'], 'name': 'Total Gen', 'yaxis': 'y2'})
traces.append({'y': df['frequency'], 'name': 'Frequency', 'yaxis': 'y3'})

layout['xaxis'] = {'domain': [0.12, 0.95]}
layout['yaxis1'] = {'title': 'Actual Gen, Storage, Solar Gen', 'titlefont': {'color': 'orange'}, 'tickfont': {'color': 'orange'}}
layout['yaxis2'] = {'title': 'Total Gen', 'side': 'left', 'overlaying': 'y', 'anchor': 'free', 'titlefont': {'color': 'red'}, 'tickfont': {'color': 'red'}}
layout['yaxis3'] = {'title': 'Frequency', 'side': 'right', 'overlaying': 'y', 'anchor': 'x', 'titlefont': {'color': 'purple'}, 'tickfont': {'color': 'purple'}}
    
pio.show({'data': traces, 'layout': layout})
Run Code Online (Sandbox Code Playgroud)

图形:

鉴于这些痕迹的性质,它们彼此严重重叠,这可能会使图形解释变得困难。

有几个选项可供选择:

  • 更改range每个 y 轴的参数,使该轴仅占据图形的一部分。例如,如果数据集范围为 0-5,则将相应的yaxis range参数设置为[-15, 5],这会将跟踪推到图表顶部附近。

  • 考虑使用子图,其中可以对相似的迹线进行分组……或者每个迹线可以有自己的图形。 以下是 Plotly 关于子图的文档。

在此输入图像描述

评论(TL;DR):

此处显示的示例代码使用较低级别的 Plotly API,而不是诸如graph_objects或 之类的便捷包装器express。原因是我(个人)认为这对用户显示“幕后”发生的事情很有帮助,而不是用方便的包装器掩盖底层代码逻辑。

这样,当用户需要修改图形的更精细细节时,他们将更好地理解Plotly 为底层图形引擎 (orca) 构建的lists 和s。dict