Python-图例与饼图重叠 [英] Python - Legend overlaps with the pie chart

查看:363
本文介绍了Python-图例与饼图重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在python中使用matplotlib.图例与我的饼图重叠.尝试了"loc"的各种选项,例如"best",1、2、3 ...,但无济于事.关于如何准确提及图例位置(例如从饼图边界进行填充)或至少确保其不重叠的任何建议?

Using matplotlib in python. The legend overlaps with my pie chart. Tried various options for "loc" such as "best" ,1,2,3... but to no avail. 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?

推荐答案

简短的答案是:您可以使用 plt.legend 的参数locbbox_to_anchor以及bbox_transformmode,以将图例放置在轴或图形中.

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.


长版:

在许多情况下,根本不需要图例,并且可以通过上下文或颜色直接推断信息:

In many cases no legend is needed at all and the information can be inferred by the context or the color directly:

如果确实该地块不能没有图例,请继续执行步骤2.

If indeed the plot cannot live without a legend, proceed to step 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.

plt.legend()有两个主要参数来确定图例的位置. loc参数是最重要且本身就足够了.
例如. plt.legend(loc="upper left")将图例放置在其边界框的左上角.如果未指定其他参数,则此边界框将是整个轴.

plt.legend() has two main arguments to determine the position of the legend. The most important and in itself sufficient is the loc argument.
E.g. plt.legend(loc="upper left") placed the legend such that it sits in the upper left corner of its bounding box. If no further argument is specified, this bounding box will be the entire axes.

但是,我们可以使用bbox_to_anchor参数指定我们自己的边界框.如果给bbox_to_anchor一个2元组,例如bbox_to_anchor=(1,1)表示边界框位于轴的右上角,没有范围.然后将其用作根据loc自变量放置图例的相对点.然后它将扩展到零尺寸边界框之外.例如.如果loc"upper left",则图例的左上角位于位置(1,1),并且图例将向右和向下扩展.

However, we may specify our own bounding box using the bbox_to_anchor argument. If bbox_to_anchor is given a 2-tuple e.g. 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. It then acts as a point relative to which the legend will be placed according to the loc argument. It will then expand out of the zero-size bounding box. E.g. 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.

这个概念用于上面的情节,它告诉我们有关环球小姐大选偏见的令人震惊的真相.

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)

为了使图例不超过图形,我们使用plt.subplots_adjust在图形边缘和轴之间获得更多空间,然后图例可以占用这些空间.

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.

还有一个选择使用一个四元组作为bbox_to_anchor的选项.此问题中详细介绍了如何使用或解释此问题:
然后可以使用mode="expand"参数使图例适合指定的边界框.

There is also the option to use a 4-tuple to 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?
and one may then use the mode="expand" argument to make the legend fit into the specified bounding box.

此方法有一些有用的替代方法:

There are some useful alternatives to this approach:

代替在轴坐标中指定图例位置,可以使用图形坐标.优点是,这将允许将图例简单地放置在图形的一个角上,而无需调整其余大部分.为此,可以使用bbox_transform参数并将图形转换提供给它.然后,将赋予bbox_to_anchor的坐标解释为图形坐标.

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. The coordinates given to bbox_to_anchor are then interpreted as figure coordinates.

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

此处(1,0)是该图的右下角.由于轴与图形边缘之间的默认间距,因此足以放置图例,使其不与饼图重叠.

Here (1,0) is the lower right corner of the figure. 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, e.g.

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)

现在,在某些情况下,我们对保存的图形比在屏幕上显示的内容更感兴趣.然后我们可以简单地将图例放在图的边缘,像这样

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

,然后使用bbox_inches="tight"savefig将其保存,

but then save it using the bbox_inches="tight" to 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)

另一种方法是使用子图为图例保留空间.在这种情况下,一个子图可以使用饼图,另一个子图将包含图例.如下所示.

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")

这篇关于Python-图例与饼图重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆