Python matplotlib图例放在外侧保存时显示不完整问题解决

更多编程教程请到:菜鸟教程 https://www.piaodoo.com/

友情链接:好看站 http://www.nrso.net/

上次说到的,使用如下代码保存矢量图时,放在外侧的图例往往显示不完整:

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)
#print(x1)
#print(x2)
number = []
x11 = []
x12 = []
for i in range(20):
  number.append(i+1)
  x11.append(i+1)
  x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a') # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b') # ms is just an alias for markersize

lgnd=plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)

plt.show()

fig.savefig(‘scatter.png’,dpi=600)

保存为scatter.png之后的效果为:

可以看到放在图像右上的图例只显示了左边一小部分。

这里的原因很简单,使用savefig()函数进行保存矢量图时,它是通过一个bounding box (bbox, 边界框),进行范围的框定,只将落入该框中的图像进行保存,如果图例没有完全落在该框中,自然不能被保存。

懂得了其原理,再进行解决问题就比较简单了。

这里有两个解决思想:

1. 将没有完全落入该bbox的图像,通过移动的方法,使其完全落入该框中,那么bbox截取的图像即是完整的 (将图像移入bbox中);

2. 改变bbox的大小,使其完全包含该图像,尤其是往往落入bbox外侧的图例 (将bbox扩大到完全包含图像)。

下面分别介绍基于这两个思想解决这个问题的两种方法:

1.  利用函数subplots_adjust()

在该官方文档中可以看到,subplots_adjust()函数的作用是调整子图布局,它包含6个参数,其中4个参数left, right, bottom, top的作用是分别调整子图的左部,右部,底部,顶部的位置,另外2个参数wspace, hspace的作用分别是调整子图之间的左右之间距离和上下之间距离。

其默认数值分别为:

以上述图为例,现考虑既然图例右侧没有显示,则调整subplots_adjust()函数的right参数,使其位置稍往左移,将参数right默认的数值0.9改为0.8,那么可以得到一个完整的图例:

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)
#print(x1)
#print(x2)
number = []
x11 = []
x12 = []
for i in range(20):
  number.append(i+1)
  x11.append(i+1)
  x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a') # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b') # ms is just an alias for markersize

lgnd=plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)

fig.subplots_adjust(right=0.8)

plt.show()

fig.savefig(‘scatter1.png’,dpi=600)

保存为scatter1.png之后和scatter.png的对比效果为: 

可以看到这时scatter1.png的图例显示完整,它是通过图像的右侧位置向左移动而被整体包含在保存的图像中完成的。

同理,若legend的位置在图像下侧,使用savefig()保存时也是不完整的,这时需要修改的是函数subplots_adjust()的参数bottom,使其向上移,而被包含在截取图像进行保存的框中,即下文介绍的bbox。

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)
#print(x1)
#print(x2)
number = []
x11 = []
x12 = []
for i in range(20):
  number.append(i+1)
  x11.append(i+1)
  x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a') # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b') # ms is just an alias for markersize

lgnd=plt.legend(bbox_to_anchor=(0.4, -0.1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)

plt.show()
fig.savefig(‘scatter#1.png’,dpi=600)

由于subplots_adjust()中默认的bottom值为0.1,故添加fig.subplots_adjust(bottom=0.2),使其底部上移,修改为 

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)
#print(x1)
#print(x2)
number = []
x11 = []
x12 = []
for i in range(20):
  number.append(i+1)
  x11.append(i+1)
  x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a') # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b') # ms is just an alias for markersize

lgnd=plt.legend(bbox_to_anchor=(0.4, -0.1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)

fig.subplots_adjust(bottom=0.2)

plt.show()
fig.savefig(‘scatter#1.png’,dpi=600)

效果对比:

图例legend在其它位置同理。 

2. 利用函数savefig()

上个博客讲到,使用savefig()函数中的三个参数fname, dpi, format可用以保存矢量图,现用该函数中另一个参数bbox_inches使

未保存到图中的图例包含进来。

下图可以看到,bbox_inches的作用是调整图的bbox, 即bounding box(边界框)

 可以看到,当bbox_inches设为'tight'时,它会计算出距该图像的较紧(tight)边界框bbox,并将该选中的框中的图像保存。

这里的较紧的边界框应该是指完全包含该图像的一个矩形,但和图像有一定的填充距离,和Minimum bounding box(最小边界框),个人认为,有一定区别。单位同样是英寸(inch)。

这样图例就会被bbox包含进去,进而被保存。

完整代码:

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)
#print(x1)
#print(x2)
number = []
x11 = []
x12 = []
for i in range(20):
  number.append(i+1)
  x11.append(i+1)
  x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a') # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b') # ms is just an alias for markersize

lgnd=plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)

#fig.subplots_adjust(right=0.8)

plt.show()

fig.savefig(‘scatter2.png’,dpi=600,bbox_inches=‘tight’)

保存为scatter2.png,下面是scatter.png, scatter1.png, scatter2.png三张图的对比:

可以看到,scatter1.png,即第1种方法的思想,是将图像的右侧边界向左移动,截取该图用以保存的bbox未变;而scatter2.png,即第2种方法的思想,是直接将截取该图用以保存的bbox扩大为整个图像,而将其全部包括。

注:savefig()还有两个参数需要说明

其中一个是pad_inches,它的作用是当前面的bbox_inches为'tight'时,调整图像和bbox之间的填充距离,这里不需要设置,只要选择默认值即可。

个人认为,如果设置pad_inches参数为0,即pad_inches=0,截取图进行保存的bbox就是minimum bounding box (最小边界框)。 

另外一个是bbox_extra_artists,它的作用是计算图像的bbox时,将其它的元素也包含进去。

这里举个例子,如果在图像左侧再加一个文本框text,保存图像时希望该文本框包含在bbox中,则可以使用该参数bbox_extra_artists将text包含进去(实际使用中,即使未使用bbox_extra_artists,保存的图像也包含该text):

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)
#print(x1)
#print(x2)
number = []
x11 = []
x12 = []
for i in range(20):
  number.append(i+1)
  x11.append(i+1)
  x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a') # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b') # ms is just an alias for markersize

lgnd=plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)

text = ax.text(-0.3,1, “test”, transform=ax.transAxes)

#fig.subplots_adjust(right=0.8)
plt.show()
fig.savefig(‘scatter3.png’,dpi=600, bbox_extra_artists=(lgnd,text),bbox_inches=‘tight’)

显示效果:

 为防止有的元素没有被包含在bbox中,可以考虑使用该参数

到此这篇关于Python matplotlib图例放在外侧保存时显示不完整问题解决的文章就介绍到这了,更多相关matplotlib外侧保存显示不完整内容请搜索菜鸟教程www.piaodoo.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持菜鸟教程www.piaodoo.com!

### 回答1: 在使用Pythonmatplotlib库画图,有会遇到图例放在外侧保存图片显示完整问题。这是由于matplotlib默认在保存图片保存图形区域,而没有保存图例区域所致。 解决问题的方法很简单,只需要在保存图片前手动调整图片边缘并设置合适的图例边距即可。具体步骤如下: 1. 在plt.savefig()函数指定保存图片的大小和分辨率,例如: plt.savefig('figure.png', dpi=300, bbox_inches='tight', pad_inches=0.1) 其dpi参数指定分辨率,bbox_inches参数按照紧凑型保存,pad_inches参数指定图例边距。 2. 在调整图例位置,可以使用legend()函数的loc参数进行控制。例如: plt.legend(loc='upper left', bbox_to_anchor=(1.02, 1)) 其loc参数指定图例位置,bbox_to_anchor参数指定图例在画布上的坐标位置。 通过上述方法,我们就可以轻松解决matplotlib图例放在外侧保存显示完整问题,使保存的图片与我们的期望相一致。 ### 回答2: Matplotlib是一个强大的Python数据可视化库,可以用来创建各种类型的图表,包括线图、散点图、柱状图、饼图等。在Matplotlib图例是一种非常重要的可视化元素,可以帮助我们更好地理解数据并提高图表的可读性。但是,有候我们在绘制图表会遇到图例放在外侧保存显示完整问题,这可能会影响我们的数据可视化效果。接下来,我将分享一些解决这个问题的方法。 第一种方法是调整图像边缘的大小。我们可以通过将图像边缘的大小扩大一些来解决图例显示完整问题。例如,我们可以使用以下代码来调整图像边缘的大小: ```python import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], label='Line 1') ax.plot([3, 2, 1], label='Line 2') ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.subplots_adjust(right=0.7) plt.savefig('figure.png', bbox_inches='tight') ``` 在这个例子,我们首先创建了一个图像,并在其绘制了两条线。然后,我们使用bbox_to_anchor参数将图例放在了图像的右上角,然后使用plt.subplots_adjust()函数调整了图像的边缘。最后,我们使用plt.savefig()函数将图像保存到本地文件,并使用bbox_inches参数指定了图像边缘的大小。 第二种方法是将图例放在子图之。我们可以将图例放在子图之,然后使用tight_layout()函数自动调整子图和图例的位置。例如,我们可以使用以下代码来将图例放在子图之: ```python import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], label='Line 1') ax.plot([3, 2, 1], label='Line 2') ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.savefig('figure.png') ``` 在这个例子,我们首先创建了一个图像,并在其绘制了两条线。然后,我们使用bbox_to_anchor参数将图例放在了图像的右上角,然后使用tight_layout()函数自动调整了子图和图例的位置。最后,我们使用plt.savefig()函数将图像保存到本地文件。 总之,如果我们遇到了Matplotlib图例放在外侧保存显示完整问题,可以考虑通过调整图像边缘的大小或将图例放在子图之的方法来解决。这些方法非常简单易行,可以帮助我们更好地展示数据并提高图表的可读性。 ### 回答3: 问题描述: 在使用Pythonmatplotlib库绘制图形,有需要将图例放在外侧。然而,当将图例放在外侧保存图形,有会出现图例显示完整问题,如下图所示: 问题原因: 这个问题的原因是,当将图例放在外侧matplotlib会自动调整图例的大小以适应图例的位置。然而,如果图例的大小太大,将会超出图像的范围,导致图例显示完整解决办法: 有多种方法可以解决这个问题,我将介绍其两种方法: 方法一:调整figure的大小 可以通过调整figure的大小来解决这个问题。具体地说,我们可以增大figure的宽度,以便使图例可以完整显示。例如,可以使用以下代码: ```python import matplotlib.pyplot as plt fig = plt.figure(figsize=(8, 6)) # 调整figure的大小 ax = fig.add_subplot(111) ax.plot([1, 2, 3], [4, 5, 6], label='Line 1') ax.plot([1, 2, 3], [6, 5, 4], label='Line 2') ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0) # 将图例放在右上角 plt.savefig('figure.png', bbox_inches='tight') # 保存图形,注意要加上bbox_inches='tight'参数 plt.show() ``` 这个方法的思路是,通过增大figure的宽度,将图例完整地放置在右侧,使得图例可以完整显示在图外侧。注意,在保存图形,要加上`bbox_inches='tight'`参数,以便将整个图像保存在文件。 方法二:调整图例的尺寸 另一种解决方法是,调整图例的尺寸,使得图例可以适应图外侧的位置。可以使用以下代码: ```python import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) ax.plot([1, 2, 3], [4, 5, 6], label='Line 1') ax.plot([1, 2, 3], [6, 5, 4], label='Line 2') legend = ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0) plt.setp(legend.get_lines(), linewidth=2) # 设置图例线条的粗细 plt.savefig('figure.png', bbox_inches='tight') # 保存图形,注意要加上bbox_inches='tight'参数 plt.show() ``` 这个方法的思路是,将图例的尺寸调整到适合的大小,使得图例可以完整显示在图外侧。可以使用`plt.setp()`函数来设置图例线条的粗细和其他属性。同样地,在保存图形,要加上`bbox_inches='tight'`参数。 总结: 在使用Pythonmatplotlib库绘制图形,如果需要将图例放在外侧保存图形,可能会出现图例显示完整问题解决这个问题的方法有多种,其两种方法分别是通过调整figure的大小和调整图例的尺寸。在应用这些方法,需要注意保存图形加上`bbox_inches='tight'`参数,以便将整个图像保存在文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值