Search code examples
pythonplotly

Reduce size between table subplots


I'm trying to add two tables to a report but am having issues with the space between the tables. By way of an MRE:

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


def main():
    fig = make_subplots(
        rows=2,
        cols=1,
        vertical_spacing=0,
        subplot_titles=("Overall summary", "Year"),
        specs=[
            [{"type": "table"}],
            [{"type": "table"}],
        ],
    )

    df1 = pd.DataFrame(
        {
            "all": {0: 1},
            "n_match": {0: 1219076},
            "n_odds": {0: 228758},
            "acc": {0: 0.735},
        }
    )

    fig.add_table(
        header=dict(
            values=list(df1.columns),
            align="right",
        ),
        cells=dict(
            values=[df1[k].tolist() for k in df1.columns[0:]],
            align="right",
        ),
        row=1,
        col=1,
    )

    df2 = pd.DataFrame(
        {
            "year": {
                0: 2009,
                1: 2010,
                2: 2011,
                3: 2012,
                4: 2013,
                5: 2014,
                6: 2015,
                7: 2016,
                8: 2017,
                9: 2018,
                10: 2019,
                11: 2020,
                12: 2021,
                13: 2022,
                14: 2023,
            },
            "n_match": {
                0: 79510,
                1: 77020,
                2: 80496,
                3: 86096,
                4: 89434,
                5: 93976,
                6: 96190,
                7: 97396,
                8: 96578,
                9: 92086,
                10: 76258,
                11: 27054,
                12: 67464,
                13: 85188,
                14: 74330,
            },
            "n_odds": {
                0: 4422,
                1: 4756,
                2: 5010,
                3: 5556,
                4: 6288,
                5: 15644,
                6: 17166,
                7: 16632,
                8: 15952,
                9: 16060,
                10: 18232,
                11: 9908,
                12: 34294,
                13: 40430,
                14: 18408,
            },
            "acc": {
                0: 0.734,
                1: 0.734,
                2: 0.742,
                3: 0.743,
                4: 0.743,
                5: 0.75,
                6: 0.748,
                7: 0.747,
                8: 0.745,
                9: 0.733,
                10: 0.718,
                11: 0.707,
                12: 0.715,
                13: 0.718,
                14: 0.715,
            },
        }
    )
    
    fig.add_table(
        header=dict(
            values=list(df2.columns),
            align="right",
        ),
        cells=dict(
            values=[df2[k].tolist() for k in df2.columns[0:]],
            align="right",
        ),
        row=2,
        col=1,
    )
    
    fig.update_layout(width=500, height=850, title_text="Report")
    
    fig.show()


if __name__ == "__main__":
    main()

This creates the following plot:

enter image description here

Things I've tried:

  1. Adjusting the height in fig.update_layout but less than 850 cuts the bottom off the second table
  2. The vertical_spacing parameter in make_sub_plots doesn't go negative
  3. I can't set different rowspan values for the specs parameter in make_sub_plots

How would I reduce the size of the gap between the tables?


Solution

  • You can try those two adjustments for make_subplots and update_layout :

        fig = make_subplots(
            rows=2,
            cols=1,
            vertical_spacing=0,
            subplot_titles=("Overall summary", "Year"),
            specs=[
                [{"type": "table"}],
                [{"type": "table"}],
            ],  # add the parameter below
                row_heights=[0.2, 0.8]  # <<< 20% (1st ta) against 80% (2nd ta)
        )
    
        fig.update_layout(
            width=500,
            height=550, # << I decrease it
            title_text="Report",
            margin=dict(b=0) # << and added this one
        )
    

    Output :

    enter image description here