绘制具有 2 个 y 轴的单迹线

问题描述 投票:0回答:1

我有一个绘图对象条形图,我想为其显示 2 个 y 轴(不同的货币,因此转换因子是常数)。

目前我每条绘制 1 条轨迹,而对于第二条轨迹,我将不透明度设置为 0,禁用图例和悬停信息。这个 hack 有效,但维护起来很难。

我知道https://plotly.com/python/multiple-axes/

我当前的解决方案看起来像这样

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

# make up some data
dates = pd.DataFrame(pd.date_range('1/1/2023','1/7/2023'), columns=['date'])
dates["key"] = 0
items = pd.DataFrame(["A","B","C"], columns=['items'])
items["key"] = 0
df = dates.merge(items,on="key",how="outer").drop("key",axis=1)
df['price_USD'] = np.random.randint(0, 100, df.shape[0])
df['price_EURO'] = df['price_USD']/1.5

fig = make_subplots(specs=[[{"secondary_y": True}]])  
for item, _df in df.groupby("items",sort=True):
    ## we may set the colors of the individual items manually here
    fig.add_trace(
                go.Bar(
                    x=_df["date"],
                    y=_df["price_USD"],
                    showlegend=True,
                    name=item,
                    opacity=1.0,
                    #color=color,
                    legendgroup=item

                ),
                secondary_y=False,
            )

    # invisible trace
    fig.add_trace(
                go.Bar(
                    x=_df["date"],
                    y=_df["price_EURO"],
                    showlegend=False,
                    opacity=0.0,
                    name="",
                    hoverinfo="skip",
                    legendgroup=item
                ),
                secondary_y=True,
            )

fig.update_layout(barmode="stack")
fig.update_yaxes(title_text="<b>Cost USD", secondary_y=False)
fig.update_yaxes(title_text="<b>Cost Euro", showgrid=False, secondary_y=True)
fig.show()

enter image description here

有没有更干净的方法来做到这一点?

python plotly visualization multiple-axes
1个回答
5
投票

可以使用另一侧作为

scaleanchor
并提供缩放。这样就不再需要将数据加倍了。

import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
np.random.seed(1)

RATIO = 1.5

# make up some data
dates = pd.DataFrame(pd.date_range('1/1/2023','1/7/2023'), columns=['date'])
dates["key"] = 0
items = pd.DataFrame(["A","B","C"], columns=['items'])
items["key"] = 0
df = dates.merge(items,on="key",how="outer").drop("key",axis=1)
df['price_USD'] = np.random.randint(0, 100, df.shape[0])

# This is not needed more, at least for displaying it
#df['price_EURO'] = df['price_USD']/ RATIO

fig = make_subplots(specs=[[{"secondary_y": True}]])  
for item, _df in df.groupby("items",sort=True):
    ## we may set the colors of the individual items manually here
    fig.add_trace(
                go.Bar(
                    x=_df["date"],
                    y=_df["price_USD"],
                    showlegend=True,
                    name=item,
                    opacity=1.0,
                    #color=color,
                    legendgroup=item

                ),
                secondary_y=False,

            )
 
# Add a dummy trace to activate the second axis  
fig.add_trace(
            go.Bar(visible=False),
            secondary_y=True,
        )
fig.update_layout(barmode="stack")
fig.update_yaxes(title_text="<b>Cost USD", secondary_y=False)
fig.update_yaxes(title_text="<b>Cost Euro", showgrid=False, secondary_y=True)
# Set scale according to the other axis and the defined ratio
# the constraint assures that it is bottom aligned
fig.update_layout(yaxis2=dict(scaleanchor="y1", scaleratio=RATIO, constraintoward="bottom"))
fig.show()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.