Search code examples
pythonmatplotliblegendlegend-properties

anchor two legends for the same plot in line one line


I have a plot with two legends that are not of the same height. I would like to place them such that their titles start at the same place on the y-axis. I know I could go and manually change bbox_to_anchor=(-0.1, -0.3) but I would have to redo it each time there are minor changes. Is there no way to set this automatically?

fig = plt.figure(1)
ax = fig.add_subplot(1, 1, 1)
xticks = mtick.FormatStrFormatter(fmt)
yticks = mtick.FormatStrFormatter(fmt)
x1 = plt.scatter([1,2],[2,3], color='b')
x2 = plt.scatter([2,3],[4,3], color='r')
x3 = plt.scatter([1,3],[4,5], color='k')
x4 = plt.scatter(0, 0, color='white')
marker1 = 'marker 1'
marker2 = 'marker 2'
marker3 = 'marker 3'
plt.xlabel("x axis")
plt.ylabel("y axis")
marker4 = ('some text that needs to go here too'+'\n'+'and is very important and just way too long so that it wont ever look good')
legend_two = plt.legend([x1, x4],[marker1, marker4],fontsize=8,
                           title='some other title', title_fontsize=10,
                           bbox_to_anchor=(0.5, -0.3), ncol=1, loc="center left", borderaxespad=0)
plt.legend([x1,x2,x3], [marker1,marker2,marker3], fontsize=8,
           title='some title', title_fontsize=10,
           bbox_to_anchor=(-0.1, -0.3), ncol=3, loc="center left", borderaxespad=0)
plt.gca().add_artist(legend_two)
plt.tight_layout()
plt.show()

Solution

  • In this case, if the coordinate axis of the bounding box is used as the FIGURE reference, it will be displayed at a fixed position without being affected by others. See here for more information on coordinate axes. For other examples of responses, please refer to this.

    import matplotlib.pyplot as plt
    from matplotlib import ticker
    
    fmt = '$%g$'
    fig = plt.figure(1)
    ax = fig.add_subplot(1, 1, 1)
    xticks = ticker.FormatStrFormatter(fmt)
    yticks = ticker.FormatStrFormatter(fmt)
    x1 = plt.scatter([1,2],[2,3], color='b')
    x2 = plt.scatter([2,3],[4,3], color='r')
    x3 = plt.scatter([1,3],[4,5], color='k')
    x4 = plt.scatter(0, 0, color='white')
    marker1 = 'marker 1'
    marker2 = 'marker 2'
    marker3 = 'marker 3'
    plt.xlabel("x axis")
    plt.ylabel("y axis")
    marker4 = ('some text that needs to go here too'+'\n'+'and is very important and just way too long so that it wont ever look good')
    legend_two = plt.legend([x1, x4],[marker1, marker4],
                            fontsize=8,
                            title='some other title',
                            title_fontsize=10,
                            bbox_to_anchor=(0.5, 0.0), #update
                            bbox_transform=fig.transFigure, # update
                            ncol=1,
                            loc="upper left",
                            borderaxespad=0)
    plt.legend([x1,x2,x3], [marker1,marker2,marker3],
               fontsize=8,
               title='some title',
               title_fontsize=10,
               bbox_to_anchor=(0.0, 0.0), # update
               bbox_transform=fig.transFigure, # update
               ncol=3,
               loc="upper left",
               borderaxespad=0)
    plt.gca().add_artist(legend_two)
    plt.tight_layout()
    plt.show()
    

    enter image description here