What's the correct way to set layout properties for each subplot?

Hi,

Just made a basic 2 by 2 subplot:

fig = make_subplots(
    rows=2, cols=2, 
    subplot_titles=[
        'Receiver Operating Characteristic', 
        'TPR vs FPR', 
        'Precision-Recall Curve', 
        'Precision vs Recall'
    ],
)

and after adding traces to each subplot I want to update the layout for each subplot, common properties like plot width, height, xaxis, yaxis, title, etc.

fig.update_layout(    
    {    
        'xaxis':{'range': [0, 1], 'dtick': 0.2,},
        'yaxis':{'range': [0, 1], 'dtick': 0.2,},
        'xaxis2':{'range': [0, 1], 'dtick': 0.2,},
        'yaxis2':{'range': [0, 1], 'dtick': 0.2,},
        'xaxis3':{'range': [0, 1], 'dtick': 0.2,},
        'yaxis3':{'range': [0, 1], 'dtick': 0.2,},
        'xaxis4':{'range': [0, 1], 'dtick': 0.2,},
        'yaxis4':{'range': [0, 1], 'dtick': 0.2,},
        'height':800,
        'width':800,
        'template':'plotly_white'
    }
)

So my questions are:

  1. How do I update layout for each subplot programatically, instead of the brutal way of copying & pasting mannually? Something like a template layout for each subplot? The naming of xaxis, xaxis2, xaxis3 feels especially suspicious to me.
  2. Why do we specify subplot title subplot_titles as a list in make_subplots, instead of title, title1 inside fig.update_layout when xaxis, xaxis2 is part of the design language.
  3. Coming from the matplotlib world, where each subplot is a standalone figure, which can be modified however one wants, I do wander if there is similar way to do this in Plotly. Thanks
1 Like

Hi Jingw222! Have you had the opportunity to look at This page? I think it may answer most if not all of your questions!

1 Like

Hi @jingw222 maybe you indeed found some answers in the tutorial suggested by @Krichardson. If you want to update all or some axes, you can use the fig.update_xaxes method as described in https://plot.ly/python/subplots/#customizing-subplot-axes. For your example, that would be

import plotly.graph_objects as go
fig = make_subplots(
    rows=2, cols=2, 
    subplot_titles=[
        'Receiver Operating Characteristic', 
        'TPR vs FPR', 
        'Precision-Recall Curve', 
        'Precision vs Recall'
    ],
)
fig.add_trace(go.Scatter(x=[0, 1], y=[0, 1]), 1, 1)
fig.add_trace(go.Scatter(x=[0, 1], y=[0, 1]), 1, 2)
fig.add_trace(go.Scatter(x=[0, 1], y=[0, 1]), 2, 1)
fig.add_trace(go.Scatter(x=[0, 1], y=[0, 1]), 2, 2)

fig.update_xaxes(range=[0, 1], dtick=0.2)
fig.update_yaxes(range=[0, 1], dtick=0.2)
fig.update_layout(height=800, width=600, template='plotly_white')
fig.show()

Titles of subplots are in fact annotations (https://plot.ly/python/text-and-annotations/), so passing them in the make_subplots function is a convenient way to have their location computed automatically for you (this is done in python and not by the javascript library which is doing all the plotting).

For updating subplots, you can use fig.update_xaxes and fig.update_traces which take a row and col parameter so that you can modify each subplot independently.

2 Likes

Thank you for clarifying that. Makes a lot sense now. If both update_traces and update_xaxes can be applied to each individual subplot separately, that seems promising and exactly what Iโ€™ve been looking for.

1 Like

Iโ€™ve been trying to do this for scatter3D in a subplot, but canโ€™t seem to figure it out. What is the correct way to call it in that case?