loc='best' 并非智能算法,而是暴力遍历10种预设位置并选择与坐标轴范围重叠最小者,完全忽略图中线条、散点、文字等实际元素,因此在多子图、tight_layout、aspect设置或存在浮动文本时极易失效。
loc='best' 并不是智能算法,而是暴力遍历 10 种预设位置('upper right'、'lower left' 等),选其中重叠面积最小的那个。它只考虑 legend 框与坐标轴范围(axes bbox)的重叠,**完全忽略图中实际绘制的线条、散点、文字等元素**。所以当你有密集折线、大 marker 或标题/标签靠边时,loc='best' 很可能把 legend 压在数据上,看似“自动”,实则不可靠。
常见失效场景包括:
subplots)中,legend 只检测当前 axes,不感知其他子图区域plt.tight_layout() 或 fig.subplots_adjust() 后,axes 实际范围变化,但 loc='best' 仍按原始 bbox 计算ax.set_aspect('equal') 或设置了非默认 anchor,导致 bbox 形变,重叠判断失准ax.text()、ax.annotate() 等浮动元素,loc='best' 
手动指定 + 微调仍是主流做法,但可借助工具减少试错:
ax.legend(loc='upper left', bbox_to_anchor=(1.02, 1.0), borderaxespad=0) 将 legend 放到图右侧外——这是最常用且稳定的布局,尤其适合横向长图ax.legend() 不指定 loc,再执行 plt.tight_layout(),最后用 ax.get_legend().set_draggable(True) 手动拖到满意位置(仅限交互环境如 Jupyter)matplotlib.pyplot.legend(bbox_to_anchor=(x, y), loc='center') 配合 fig.transFigure 坐标系,例如 bbox_to_anchor=(0.5, 0.02), loc='lower center' 放底部居中,避开所有数据区Matplotlib 本身不提供数据感知型 legend 定位。若必须动态避让,需自行计算:
for line in ax.lines: print(line.get_window_extent())(需先 draw)ax.get_tightbbox(renderer) 获取图中所有元素的总包围盒bbox_to_anchor 值这已超出 loc='best' 范畴,属于定制化布局逻辑,且 renderer 依赖后端,跨环境易出错。多数情况下,固定外置位置(如右侧或底部)比追求“自动”更省心也更稳定。