减少matplotlib图中的左右边距
Posted
技术标签:
【中文标题】减少matplotlib图中的左右边距【英文标题】:Reduce left and right margins in matplotlib plot 【发布时间】:2011-05-01 19:53:07 【问题描述】:我正在努力处理我在 matplotlib 中的绘图边距。我使用下面的代码来制作我的图表:
plt.imshow(g)
c = plt.colorbar()
c.set_label("Number of Slabs")
plt.savefig("OutputToUse.png")
但是,我得到一个输出图,图的两边都有很多空白。我搜索了谷歌并阅读了 matplotlib 文档,但我似乎找不到如何减少这种情况。
【问题讨论】:
问题是imshow
图形的extent
中的空白数量,还是图形周围生成的png中边框空白的数量,由savefig
生成?跨度>
我认为两者都 - 在查看窗口和 PNG 中似乎都有很多空间。但是,重要的输出是savefig
生成的 png 文件 - 所以这就是我想要排序的内容。
后来我刚刚在 GIMP 中裁剪了它们。 ://
ax.margins(x=0.01) 就是你要找的东西!
【参考方案1】:
请删除程序中的键“sharex=True 和 sharey=True”。我想你没有在这里上传完整的程序。希望我的回答对您的查询有所帮助。
【讨论】:
【参考方案2】:# import pyplot
import matplotlib.pyplot as plt
# your code to plot the figure
# set tight margins
plt.margins(0.015, tight=True)
【讨论】:
【参考方案3】:对于最近的 matplotlib 版本,您可能想尝试Constrained Layout:
constrained_layout 自动调整子图和装饰,例如 图例和颜色条,以便它们适合图形窗口,同时 仍然尽最大努力保留所要求的逻辑布局 用户。
constrained_layout 类似于tight_layout,但使用了一个约束 求解器来确定允许它们适合的轴的大小。
constrained_layout 需要在添加任何轴之前激活 一个数字。
太糟糕了pandas does not handle it well...
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review【参考方案4】:有时,plt.tight_layout()
无法提供最佳视图或我想要的视图。那么为什么不先绘制任意边距,然后在绘制后固定边距呢?
因为我们从那里得到了很好的所见即所得。
import matplotlib.pyplot as plt
fig,ax = plt.subplots(figsize=(8,8))
plt.plot([2,5,7,8,5,3,5,7,])
plt.show()
然后将设置粘贴到边距功能中以使其永久化:
fig,ax = plt.subplots(figsize=(8,8))
plt.plot([2,5,7,8,5,3,5,7,])
fig.subplots_adjust(
top=0.981,
bottom=0.049,
left=0.042,
right=0.981,
hspace=0.2,
wspace=0.2
)
plt.show()
【讨论】:
这真是一个很好的提示 - 我从来没有发现那里的“导出”按钮.. 谢谢。 这真的帮助我处理了子图的边界【参考方案5】:如果有人想知道在应用plt.tight_layout()
或fig.tight_layout()
后如何去除剩余的白边:使用参数pad
(默认为1.08
),您可以让它更紧:
“图形边缘和子图边缘之间的填充,作为字体大小的一部分。”
比如
plt.tight_layout(pad=0.05)
会将其减少到非常小的余量。输入0
对我不起作用,因为它也会使子图的框被切掉一点。
【讨论】:
我使用pad=0.5
代替,因为我立即遇到了这种剪辑内容的情况:如果最高 y 轴刻度线靠近绘图区域的顶部,那么它的标签将被切断。不错的提示,我是来找这个的。【参考方案6】:
自动执行此操作的一种方法是将bbox_inches='tight'
kwarg 转换为plt.savefig
。
例如
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(3000).reshape((100,30))
plt.imshow(data)
plt.savefig('test.png', bbox_inches='tight')
另一种方法是使用fig.tight_layout()
import matplotlib.pyplot as plt
import numpy as np
xs = np.linspace(0, 1, 20); ys = np.sin(xs)
fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.plot(xs, ys)
# This should be called after all axes have been added
fig.tight_layout()
fig.savefig('test.png')
【讨论】:
有什么办法让它成为默认值吗? 如果您有多个子图并且想要保存每个子图,您也可以将其与fig.savefig()
一起使用。 (plt.savefig()
在这种情况下不起作用。)
所有这一切都是在图像被渲染后裁剪;如果您尝试强制执行特定分辨率,则图像会变小。
@detly - 是的。这正是它所做的(尽管它也可以“裁剪”出来并使图像更大)。对于您想要的内容,请查看fig.tight_layout()
。最初编写此答案时该功能不存在,否则我会更突出地提及它。
如果有人有问题,请使用fig = plt.gcf()
【参考方案7】:
只需使用ax = fig.add_axes([left, bottom, width, height])
如果您想精确控制图形布局。例如。
left = 0.05
bottom = 0.05
width = 0.9
height = 0.9
ax = fig.add_axes([left, bottom, width, height])
【讨论】:
【参考方案8】:受上述 Sammys 回答的启发:
margins = # vvv margin in inches
"left" : 1.5 / figsize[0],
"bottom" : 0.8 / figsize[1],
"right" : 1 - 0.3 / figsize[0],
"top" : 1 - 1 / figsize[1]
fig.subplots_adjust(**margins)
其中 figsize 是您在 fig = pyplot.figure(figsize=...)
中使用的元组
【讨论】:
【参考方案9】:对我来说,上面的答案不适用于 Win7 上的 matplotlib.__version__ = 1.4.3
。因此,如果我们只对图像本身感兴趣(即,如果我们不需要注释、轴、刻度、标题、ylabel 等),那么最好将 numpy 数组简单地保存为图像而不是savefig
。
from pylab import *
ax = subplot(111)
ax.imshow(some_image_numpyarray)
imsave('test.tif', some_image_numpyarray)
# or, if the image came from tiff or png etc
RGBbuffer = ax.get_images()[0].get_array()
imsave('test.tif', RGBbuffer)
另外,使用opencv绘图函数(cv2.line,cv2.polylines),我们可以直接在numpy数组上做一些绘图。 http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html
【讨论】:
【参考方案10】:你只需要
plt.tight_layout()
在你的输出之前。
除了减少边距之外,这还紧密地组合了任何子图之间的空间:
x = [1,2,3]
y = [1,4,9]
import matplotlib.pyplot as plt
fig = plt.figure()
subplot1 = fig.add_subplot(121)
subplot1.plot(x,y)
subplot2 = fig.add_subplot(122)
subplot2.plot(y,x)
fig.tight_layout()
plt.show()
【讨论】:
我认为这确实是最好的方法。它不需要像 `bbox='tight' 那样保存图形,并修复了狭窄图形中的各种其他布局问题。 这应该是正确的答案,因为它的行为符合您的预期,因为它适用于图形而不是图像。 奇怪的是,与bbox_inches='tight'
相比,这也改变了 实际绘图 的宽度(即峰更靠近),它只是剪裁了边缘周围的空白区域但不理会情节。我用plt.figure(figsize=(10,3))
创建了这个图。【参考方案11】:
matplotlibs subplots_adjust 的问题是你输入的值是相对于图形的 x 和 y figsize 的。此示例用于正确打印 pdf 的数字:
为此,我将相对间距重新计算为绝对值,如下所示:
pyplot.subplots_adjust(left = (5/25.4)/figure.xsize, bottom = (4/25.4)/figure.ysize, right = 1 - (1/25.4)/figure.xsize, top = 1 - (3/25.4)/figure.ysize)
对于 x 维度的“figure.xsize”英寸和 y 维度的“figure.ysize”英寸的图形。因此,整个图形的左边距为 5 毫米,下边距为 4 毫米,右边为 1 毫米,顶部为 3 毫米,放置在标签内。 (x/25.4) 的转换已经完成,因为我需要将 mm 转换为英寸。
请注意,x 的纯图表大小将为“figure.xsize - 左边距 - 右边距”,y 的纯图表大小将为“figure.ysize - 下边距 - 上边距”,以英寸为单位
其他片段(不确定这些片段,我只是想提供其他参数)
pyplot.figure(figsize = figureSize, dpi = None)
和
pyplot.savefig("outputname.eps", dpi = 100)
【讨论】:
你从哪里得到xsize
和ysize
。我使用这些属性,我得到AttributeError: 'Figure' object has no attribute 'xsize'
【参考方案12】:
您可以使用 subplots_adjust() 函数调整 matplotlib 图形周围的间距:
import matplotlib.pyplot as plt
plt.plot(whatever)
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
这适用于屏幕上的图形和保存到文件中,即使您在一个图形上没有多个绘图,它也是正确调用的函数。
数字是图形尺寸的分数,需要调整以允许图形标签。
【讨论】:
分配给参数的值而不是改变多少,它们是设置边距的地方。换句话说,如果你想把右边距提高 10%,你应该设置 right=0.9,而不是 right=0.1 matplotlib.sourceforge.net/api/… 有必要指出,显然您可以在 plt.subplots_adjust() 中指定负值。这样做甚至可以让您在图形区域之外进行绘制,还可以处理烦人的边距。 这也适用于GridSpec
对象,方法是调用update
方法(参见***.com/a/20058199/1030876)。【参考方案13】:
plt.savefig("circle.png", bbox_inches='tight',pad_inches=-1)
【讨论】:
"pad_inches=-1" 导致我的 savefig 只生成部分图形。 在savefig
函数中使用参数是优雅的,但是pad_inches
的负值不一定在每种情况下都需要。
设置为0,有帮助以上是关于减少matplotlib图中的左右边距的主要内容,如果未能解决你的问题,请参考以下文章
如何减少/删除分组 UITableView 中的左/右手边距?
Python matplotlib图例如何减少框架左边缘和标记之间的距离