How to specify legend position in matplotlib in graph coordinates

前端 未结 4 1600
梦如初夏
梦如初夏 2020-11-29 06:52

I am aware of the bbox_to_anchor keyword and this thread, which very helpfully suggests how to manually place the legend:

How to put the legend out of the plot

相关标签:
4条回答
  • 2020-11-29 07:36

    You can change location of legend using loc argument. https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.legend

    import matplotlib.pyplot as plt
    
    plt.subplot(211)
    plt.plot([1,2,3], label="test1")
    plt.plot([3,2,1], label="test2")
    # Place a legend above this subplot, expanding itself to
    # fully use the given bounding box.
    plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
               ncol=2, mode="expand", borderaxespad=0.)
    
    plt.subplot(223)
    plt.plot([1,2,3], label="test1")
    plt.plot([3,2,1], label="test2")
    # Place a legend to the right of this smaller subplot.
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    
    plt.show()
    
    0 讨论(0)
  • 2020-11-29 07:36

    According to the matplotlib legend documentation:

    The location can also be a 2-tuple giving the coordinates of the lower-left corner of the legend in axes coordinates (in which case bbox_to_anchor will be ignored).

    Thus, one could use:

    plt.legend(loc=(x, y))
    

    to set the legend's lower left corner to the specified (x, y) position.

    0 讨论(0)
  • 2020-11-29 07:50

    The loc parameter specifies in which corner of the bounding box the legend is placed. The default for loc is loc="best" which gives unpredictable results when the bbox_to_anchor argument is used.
    Therefore, when specifying bbox_to_anchor, always specify loc as well.

    The default for bbox_to_anchor is (0,0,1,1), which is a bounding box over the complete axes. If a different bounding box is specified, is is usually sufficient to use the first two values, which give (x0, y0) of the bounding box.

    Below is an example where the bounding box is set to position (0.6,0.5) (green dot) and different loc parameters are tested. Because the legend extents outside the bounding box, the loc parameter may be interpreted as "which corner of the legend shall be placed at position given by the 2-tuple bbox_to_anchor argument".

    import matplotlib.pyplot as plt
    plt.rcParams["figure.figsize"] = 6, 3
    fig, axes = plt.subplots(ncols=3)
    locs = ["upper left", "lower left", "center right"]
    for l, ax in zip(locs, axes.flatten()):
        ax.set_title(l)
        ax.plot([1,2,3],[2,3,1], "b-", label="blue")
        ax.plot([1,2,3],[1,2,1], "r-", label="red")
        ax.legend(loc=l, bbox_to_anchor=(0.6,0.5))
        ax.scatter((0.6),(0.5), s=81, c="limegreen", transform=ax.transAxes)
    
    plt.tight_layout()    
    plt.show()
    

    See especially this answer for a detailed explanation and the question What does a 4-element tuple argument for 'bbox_to_anchor' mean in matplotlib? .


    If you want to specify the legend position in other coordinates than axes coordinates, you can do so by using the bbox_transform argument. If may make sense to use figure coordinates

    ax.legend(bbox_to_anchor=(1,0), loc="lower right",  bbox_transform=fig.transFigure)
    

    It may not make too much sense to use data coordinates, but since you asked for it this would be done via bbox_transform=ax.transData.

    0 讨论(0)
  • 2020-11-29 07:55

    In addition to @ImportanceOfBeingErnest's post, I use the following line to add a legend at an absolute position in a plot.

    plt.legend(bbox_to_anchor=(1.0,1.0),\
        bbox_transform=plt.gcf().transFigure)
    

    For unknown reasons, bbox_transform=fig.transFigure does not work with me.

    0 讨论(0)
提交回复
热议问题