Search code examples
pythonmatplotlibseabornlegendseaborn-objects

How to reposition Figure legends into subfigures


I am new to this, trying to plot 2 subfigures horizontal with sample data using Matplotlib and Seaborn library in Jupyter Notebook, the 2 sub-charts come out alright, but the 2 legends overlap each other on the far right hand. I couldn't figure out a way to move legend of the 1st sub-figure to the left. Any suggestions are greatly appreciated!

screenshot

import matplotlib as mpl
tips = sns.load_dataset("tips")

f = mpl.figure.Figure(figsize=(8, 2), dpi=100)
sf1, sf2 = f.subfigures(1, 2)

(
    so.Plot(tips, "total_bill", "tip", color="day")
    .facet(col="day")
    .add(so.Dot(color="#aabc"), col=None, color=None)
    .add(so.Dot())
).on(sf1).plot()

(
    so.Plot(tips, "total_bill", "tip")
    .add(so.Dot(color="#aabc"))
    .add(so.Dot(), data=tips.query("size == 1"), color="time")
).on(sf2).plot()

Solution

  • Slight change in how the legends are assigned to each subfigure

    import seaborn as sns
    import seaborn.objects as so
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    tips = sns.load_dataset("tips")
    
    f = mpl.figure.Figure(figsize=(8, 2), dpi=100)
    sf1, sf2 = f.subfigures(1, 2)
    
    (
        so.Plot(tips, "total_bill", "tip", color="day")
        .facet(col="day")
        .add(so.Dot(color="#aabc"), col=None, color=None)
        .add(so.Dot())
        .on(sf1)
        .plot()
    )
    
    (
        so.Plot(tips, "total_bill", "tip")
        .add(so.Dot(color="#aabc"))
        .add(so.Dot(), data=tips.query("size == 1"), color="time")
        .on(sf2)
        .plot()
    )
    
    # remove the legends from the primary figure
    l2 = f.legends.pop(1)
    l1 = f.legends.pop(0)
    
    # add the legend properties to the appropriate subfigure
    sf1.legend(l1.legend_handles, [t.get_text() for t in l1.texts])
    sf2.legend(l2.legend_handles, [t.get_text() for t in l2.texts])
    
    f.figure
    

    enter image description here