How to declare multiple axes in plotly using a for loop

I am trying to define all the y-axes in a loop. Is the kwargs** the best method for this (using a loop to define multiple y axes in plotly) or could I use globals()? I cannot get my method to work. I would prefer to just run a loop just for the layout, and not for the traces. Thank you for the help

Original Example

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[1, 2, 3],
    y=[4, 5, 6],
    name="yaxis1 data"
))


fig.add_trace(go.Scatter(
    x=[2, 3, 4],
    y=[40, 50, 60],
    name="yaxis2 data",
    yaxis="y2"
))

fig.add_trace(go.Scatter(
    x=[4, 5, 6],
    y=[40000, 50000, 60000],
    name="yaxis3 data",
    yaxis="y3"
))

fig.add_trace(go.Scatter(
    x=[5, 6, 7],
    y=[400000, 500000, 600000],
    name="yaxis4 data",
    yaxis="y4"
))


# Create axis objects
fig.update_layout(
    xaxis=dict(
        domain=[0.3, 0.7]
    ),
    yaxis=dict(
        title="yaxis title",
        titlefont=dict(
            color="#1f77b4"
        ),
        tickfont=dict(
            color="#1f77b4"
        )
    ),
    yaxis2=dict(
        title="yaxis2 title",
        titlefont=dict(
            color="#ff7f0e"
        ),
        tickfont=dict(
            color="#ff7f0e"
        ),
        anchor="free",
        overlaying="y",
        side="left",
        position=0.15
    ),
    yaxis3=dict(
        title="yaxis3 title",
        titlefont=dict(
            color="#d62728"
        ),
        tickfont=dict(
            color="#d62728"
        ),
        anchor="x",
        overlaying="y",
        side="right"
    ),
    yaxis4=dict(
        title="yaxis4 title",
        titlefont=dict(
            color="#9467bd"
        ),
        tickfont=dict(
            color="#9467bd"
        ),
        anchor="free",
        overlaying="y",
        side="right",
        position=0.85
    )
)

# Update layout properties
fig.update_layout(
    title_text="multiple y-axes example",
    width=800,
)

fig.show()

My globals() example # Does not work

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[1, 2, 3],
    y=[4, 5, 6],
    name="yaxis1 data"
))


fig.add_trace(go.Scatter(
    x=[2, 3, 4],
    y=[40, 50, 60],
    name="yaxis2 data",
    yaxis="y2"
))

fig.add_trace(go.Scatter(
    x=[4, 5, 6],
    y=[40000, 50000, 60000],
    name="yaxis3 data",
    yaxis="y3"
))

fig.add_trace(go.Scatter(
    x=[5, 6, 7],
    y=[400000, 500000, 600000],
    name="yaxis4 data",
    yaxis="y4"
))


# Create axis objects
fig.update_layout(
    xaxis=dict(
        domain=[0.3, 0.7]
    ),
    yaxis=dict(
        title="yaxis title",
        titlefont=dict(
            color="#1f77b4"
        ),
        tickfont=dict(
            color="#1f77b4"
        )
    ),
    for i in range(2,5):
        globals()['yaxis' + str(i)] = dict(
            title="yaxis" + str(i) +  " title",
            overlaying= overlay[i],
            side=side[i],
            position= position[i]
        ),
    

# Update layout properties
fig.update_layout(
    title_text="multiple y-axes example",
    width=800,
)

fig.show()

The other method I thought about is to create an array of dictionaries which works for shapes in plotly. I am curious if plotly has something similar like that for y_axes

 y = [dict(
            title="yaxis" + str(i) +  " title",
            anchor= anchor[i],
            overlaying= overlay[i],
            side=side[i],
            position= position[i]
        ) for i in range (2,5)]
y_axes = y

Upvotes: 1

Views: 1155

Answers (1)

r-beginners
r-beginners

Reputation: 35155

To get layout data in a plotly graph, you can use fig.layout.

fig.layout

Layout({
    'template': '...',
    'title': {'text': 'multiple y-axes example'},
    'width': 800,
    'xaxis': {'domain': [0.3, 0.7]},
    'yaxis': {'tickfont': {'color': '#1f77b4'}, 'title': {'font': {'color': '#1f77b4'}, 'text': 'yaxis title'}},
    'yaxis2': {'anchor': 'free',
               'overlaying': 'y',
               'position': 0.15,
               'side': 'left',
               'tickfont': {'color': '#ff7f0e'},
               'title': {'font': {'color': '#ff7f0e'}, 'text': 'yaxis2 title'}},
    'yaxis3': {'anchor': 'x',
               'overlaying': 'y',
               'position': 0,
               'side': 'right',
               'tickfont': {'color': '#d62728'},
               'title': {'font': {'color': '#d62728'}, 'text': 'yaxis3 title'}},
    'yaxis4': {'anchor': 'free',
               'overlaying': 'y',
               'position': 0.85,
               'side': 'right',
               'tickfont': {'color': '#9467bd'},
               'title': {'font': {'color': '#9467bd'}, 'text': 'yaxis4 title'}}

We can create the data for this y-axis in a dictionary format and define it in fig.update_layout(), but we can't create it at once because the definitions for the basic y-axis and the other y-axis are different, so we need two y-axis settings. The description in the loop process is fig.layout[axis_name[i]]=dict(...).

# Create axis objects
fig.update_layout(
    xaxis=dict(
        domain=[0.3, 0.7]
    )
)

titles = ['yaxis2 title','yaxis3 title','yaxis4 title']
title_colors = ['#ff7f0e','#d62728','#9467bd']
anchor = ['free','x','free']
overlaying = ['y','y','y']
side = ['left','right','right']
position = [0.15, 0, 0.85]
axis_name = [y.split(' ')[0] for y in titles]

for i in range(3):
    fig.layout[axis_name[i]] = dict(
        tickfont=dict(color=title_colors[i]),
        title=dict(font=dict(color=title_colors[i]), text=titles[i]),
        anchor=anchor[i],
        overlaying=overlaying[i],
        side=side[i],
        position=position[i]
    )
    
fig.layout['yaxis'] = dict(
        tickfont=dict(color='#1f77b4'),
        title=dict(font=dict(color='#1f77b4'), text='yaxis title'),
    )

# Update layout properties
fig.update_layout(
    title_text="multiple y-axes example",
    width=800,
)

fig.show()

enter image description here

Upvotes: 1

Related Questions