简体   繁体   English

Python - Legend与饼图重叠

[英]Python - Legend overlaps with the pie chart

Using matplotlib in python. 在python中使用matplotlib。 The legend overlaps with my pie chart. 图例与我的饼图重叠。 Tried various options for "loc" such as "best" ,1,2,3... but to no avail. 尝试了“loc”的各种选项,如“最佳”,1,2,3 ...但无济于事。 Any Suggestions as to how to either exactly mention the legend position (such as giving padding from the pie chart boundaries) or at least make sure that it does not overlap? 有关如何准确提及图例位置的任何建议(例如从饼图边界给出填充)或至少确保它不重叠?

The short answer is: You may use plt.legend 's arguments loc , bbox_to_anchor and additionally bbox_transform and mode , to position the legend in an axes or figure. 简短的回答是:您可以使用plt.legend的参数locbbox_to_anchor以及bbox_transformmode来将图例定位在轴或图形中。


The long version: 长版:

Step 1: Making sure a legend is needed. 第1步:确保需要图例。

In many cases no legend is needed at all and the information can be inferred by the context or the color directly: 在许多情况下,根本不需要图例,信息可以直接由上下文或颜色推断:

在此输入图像描述

在此输入图像描述

If indeed the plot cannot live without a legend, proceed to step 2. 如果情节确实不能没有传说,请继续执行第2步。

Step 2: Making sure, a pie chart is needed. 第2步:确保需要一个饼图。

In many cases pie charts are not the best way to convey information. 在许多情况下,饼图不是传达信息的最佳方式。

在此输入图像描述

If the need for a pie chart is unambiguously determined, let's proceed to place the legend. 如果明确确定饼图的需要,让我们继续放置图例。

Placing the legend 放置图例

plt.legend() has two main arguments to determine the position of the legend. plt.legend()有两个主要参数来确定图例的位置。 The most important and in itself sufficient is the loc argument. loc参数最重要且本身就足够了。
Eg plt.legend(loc="upper left") placed the legend such that it sits in the upper left corner of its bounding box. 例如, plt.legend(loc="upper left")放置图例,使其位于其边界框的左上角。 If no further argument is specified, this bounding box will be the entire axes. 如果未指定其他参数,则此边界框将是整个轴。

However, we may specify our own bounding box using the bbox_to_anchor argument. 但是,我们可以使用bbox_to_anchor参数指定我们自己的边界框。 If bbox_to_anchor is given a 2-tuple eg bbox_to_anchor=(1,1) it means that the bounding box is located at the upper right corner of the axes and has no extent. 如果给bbox_to_anchor一个2元组,例如bbox_to_anchor=(1,1)则意味着边界框位于轴的右上角并且没有范围。 It then acts as a point relative to which the legend will be placed according to the loc argument. 然后它作为一个点,相对于图标将根据loc参数放置。 It will then expand out of the zero-size bounding box. 然后它将扩展到零大小的边界框。 Eg if loc is "upper left" , the upper left corner of the legend is at position (1,1) and the legend will expand to the right and downwards. 例如,如果loc"upper left" ,则图例的左上角位于位置(1,1),图例将向右和向下扩展。

This concept is used for the above plot, which tells us the shocking truth about the bias in Miss Universe elections. 这个概念用于上面的情节,它告诉我们关于环球小姐选举偏见的令人震惊的事实。

 import matplotlib.pyplot as plt import matplotlib.patches total = [100] labels = ["Earth", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto *"] plt.title('Origin of Miss Universe since 1952') plt.gca().axis("equal") pie = plt.pie(total, startangle=90, colors=[plt.cm.Set3(0)], wedgeprops = { 'linewidth': 2, "edgecolor" :"k" }) handles = [] for i, l in enumerate(labels): handles.append(matplotlib.patches.Patch(color=plt.cm.Set3((i)/8.), label=l)) plt.legend(handles,labels, bbox_to_anchor=(0.85,1.025), loc="upper left") plt.gcf().text(0.93,0.04,"* out of competition since 2006", ha="right") plt.subplots_adjust(left=0.1, bottom=0.1, right=0.75) 

In order for the legend not to exceed the figure, we use plt.subplots_adjust to obtain more space between the figure edge and the axis, which can then be taken up by the legend. 为了使图例不超过图形,我们使用plt.subplots_adjust在图形边缘和轴之间获得更多空间,然后可以由图例占用。

There is also the option to use a 4-tuple to bbox_to_anchor . 还可以选择将4元组用于bbox_to_anchor How to use or interprete this is detailed in this question: What does a 4-element tuple argument for 'bbox_to_anchor' mean in matplotlib? 如何使用或解释这个问题在这个问题中详细说明: 'bbox_to_anchor'的4元素元组参数在matplotlib中是什么意思?
and one may then use the mode="expand" argument to make the legend fit into the specified bounding box. 然后可以使用mode="expand"参数使图例适合指定的边界框。

There are some useful alternatives to this approach: 这种方法有一些有用的替代方案:

Using figure coordinates 使用图形坐标

Instead of specifying the legend position in axes coordinates, one may use figure coordinates. 可以使用图形坐标来代替在轴坐标中指定图例位置。 The advantage is that this will allow to simply place the legend in one corner of the figure without adjusting much of the rest. 优点是,这将允许简单地将图例放置在图形的一个角落而不调整其余部分。 To this end, one would use the bbox_transform argument and supply the figure transformation to it. 为此,可以使用bbox_transform参数并bbox_transform提供图形转换。 The coordinates given to bbox_to_anchor are then interpreted as figure coordinates. 然后将给予bbox_to_anchor的坐标解释为图形坐标。

 plt.legend(pie[0],labels, bbox_to_anchor=(1,0), loc="lower right", bbox_transform=plt.gcf().transFigure) 

Here (1,0) is the lower right corner of the figure. 这里(1,0)是图的右下角。 Because of the default spacings between axes and figure edge, this suffices to place the legend such that it does not overlap with the pie. 由于轴和图形边缘之间的默认间距,这足以放置图例,使其不与饼图重叠。

在此输入图像描述

In other cases, one might still need to adapt those spacings such that no overlap is seen, eg 在其他情况下,可能仍然需要调整这些间距,使得不会看到重叠,例如

 title = plt.title('What slows down my computer') title.set_ha("left") plt.gca().axis("equal") pie = plt.pie(total, startangle=0) labels=["Trojans", "Viruses", "Too many open tabs", "The anti-virus software"] plt.legend(pie[0],labels, bbox_to_anchor=(1,0.5), loc="center right", fontsize=10, bbox_transform=plt.gcf().transFigure) plt.subplots_adjust(left=0.0, bottom=0.1, right=0.45) 

在此输入图像描述

Saving the file with bbox_inches="tight" 使用bbox_inches="tight"保存文件

Now there may be cases where we are more interested in the saved figure than at what is shown on the screen. 现在可能存在这样的情况:我们对保存的图形比对屏幕上显示的图像更感兴趣。 We may then simply position the legend at the edge of the figure, like so 然后我们可以简单地将图例定位在图的边缘,就像这样

在此输入图像描述

but then save it using the bbox_inches="tight" to savefig , 但然后使用bbox_inches="tight"来保存它以保存savefig

 plt.savefig("output.png", bbox_inches="tight") 

This will create a larger figure, which sits tight around the contents of the canvas: 这将创建一个更大的数字,紧紧围绕画布的内容:

在此输入图像描述

A sophisticated approach, which allows to place the legend tightly inside the figure, without changing the figure size is presented here: Creating figure with exact size and no padding (and legend outside the axes) 这里介绍了一种复杂的方法,它允许将图例紧紧地放在图中,而不改变图形尺寸: 创建具有精确尺寸且没有填充的图形(以及轴外的图例)

Using Subplots 使用子图

An alternative is to use subplots to reserve space for the legend. 另一种方法是使用子图来为图例保留空间。 In this case one subplot could take the pie chart, another subplot would contain the legend. 在这种情况下,一个子图可以采用饼图,另一个子图可以包含图例。 This is shown below. 如下所示。

 fig = plt.figure(4, figsize=(3,3)) ax = fig.add_subplot(211) total = [4,3,2,81] labels = ["tough working conditions", "high risk of accident", "harsh weather", "it's not allowed to watch DVDs"] ax.set_title('What people know about oil rigs') ax.axis("equal") pie = ax.pie(total, startangle=0) ax2 = fig.add_subplot(212) ax2.axis("off") ax2.legend(pie[0],labels, loc="center") 

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM