Matplotlib:图形左边缘与y轴之间的固定间距。

时间:2022-04-17 23:43:47

I have produced 2 plots in Matplotlib with Python 2.7. The plots were saved to *.png files. After saving them, both images have the same resolution - width = 1099 pixels, height = 619 pixels.

我用Python 2.7在Matplotlib中生成了两个图。这些情节被保存到*。png文件。保存后,两幅图像的分辨率相同——宽度= 1099像素,高度= 619像素。

However, when I align the saved *.png images vertically (attached, below), the spacing between the y-axis and the left most point of the images is not the same - see a and b in the image below.Matplotlib:图形左边缘与y轴之间的固定间距。

然而,当我对齐保存的*。png图像垂直(附着,下图),y轴和左侧的图像之间的间距不是相同的——见下图中的a和b。

By this I mean, the distance from the left of the image to the y-axis is not the same (a is not equal to b).

我的意思是,从图像左边到y轴的距离不是相同的(a不等于b)。

Click on the image to zoom in and see this.

点击图像放大并看到这个。

Question: Is there a way to force the y-axis to start at a particular position relative to the left of the image?

问:有没有一种方法可以强迫y轴从一个相对于图像左侧的特定位置开始?

NOTE: I am not concerned about the space between the tick label and the axis label - I can adjust this using something like ax.yaxis.labelpad(25). However, I do not know how to fix the space between the left of the image and the y-axis.

注意:我不关心标记标签和轴标签之间的空间——我可以使用像ax.yaxis.labelpad(25)这样的东西来调整它。但是,我不知道如何修复图像左侧和y轴之间的空间。

NOTE 2: I create my plot using:

注2:我用:

fig = plt.figure(1)
ax = fig.add_subplot(111)
fig.tight_layout()

2 个解决方案

#1


1  

This is how I usually setup my code if I want to have a fine control over the size of the figure's margins in matplotlib. In addition, I show how the position of the ylabel can be setup, so you can easily align the ylabels of your two figures together.

这是我通常设置我的代码的方式,如果我想在matplotlib中对图的边缘的大小有一个精确的控制。此外,我还展示了ylabel的位置是如何设置的,所以您可以轻松地将两个数据的ylabel组合在一起。

import matplotlib.pyplot as plt

plt.close('all')

#---- create figure ----

fwidth = 8.  # total width of the figure in inches
fheight = 4. # total height of the figure in inches

fig = plt.figure(figsize=(fwidth, fheight))

#---- define margins -> size in inches / figure dimension ----

left_margin  = 0.95 / fwidth
right_margin = 0.2 / fwidth
bottom_margin = 0.5 / fheight
top_margin = 0.25 / fheight

#---- create axes ----

# dimensions are calculated relative to the figure size

x = left_margin    # horiz. position of bottom-left corner
y = bottom_margin  # vert. position of bottom-left corner
w = 1 - (left_margin + right_margin) # width of axes
h = 1 - (bottom_margin + top_margin) # height of axes

ax = fig.add_axes([x, y, w, h])

#---- Define the Ylabel position ----

# Location are defined in dimension relative to the figure size  

xloc =  0.25 / fwidth 
yloc =  y + h / 2.  

ax.set_ylabel('yLabel', fontsize=16, verticalalignment='top',
              horizontalalignment='center')             
ax.yaxis.set_label_coords(xloc, yloc, transform = fig.transFigure)

plt.show(block=False)
fig.savefig('figure_margins.png')

This results in a 8in x 4in figure, with margins of exactly 0.95, 0.2, 0.5, and 0.25 inch at the left, right, bottom and top of the figure. One benefit of this approach is that the size of the margins are defined in absolute units (inches), meaning they will remain consistent even if you change the size of the figure.

这导致了一个8in x 4in的数字,在左边,右边,底部和顶部的边缘正好是0.95,0.2,0.5,和0.25英寸。这种方法的一个好处是,边缘的大小是用绝对单位(英寸)来定义的,这意味着即使你改变了图形的大小,它们也会保持一致。

As for the ylabel, horizontally, the top of the label is located 0.25 inch from the left edge of the figure, while vertically the centre of the label corresponds to the centre of the axe. Note that due to the 90 degrees rotation on the ylabel, the meaning of the verticalalignment and horizontalalignment are in reality inverted.

至于ylabel,水平上,标签的顶部距离图形的左边缘0.25英寸,而垂直的标签的中心对应于斧头的中心。注意,由于ylabel上的90度旋转,垂直对齐和水平对齐的意义在现实中颠倒了。

Below are shown outputs of the code above with the yaxis limits set to [0, 1] and to [0, 18] respectively.

下面显示的是上述代码的输出,它们分别设置为[0,1]和[0,18]。

Matplotlib:图形左边缘与y轴之间的固定间距。 Matplotlib:图形左边缘与y轴之间的固定间距。

#2


3  

I think you can set this property (space between edge of figure and axis) when you create the axes (add_axes to a figure object). Here is some simple example code that produces two axes with generous spacing on all sides:

我认为,当您创建坐标轴(add_axes到一个图形对象)时,您可以设置这个属性(图和轴的边缘之间的空间)。下面是一些简单的示例代码,它产生了两个轴,它们的间距都很宽:

import matplotlib.pyplot as plt

f1 = plt.figure()
ax1 = f1.add_axes([0.2, 0.2, 0.6, 0.6]) # List is [left, bottom, width, height]
ax1.axis([0, 1, 0, 1])
plt.savefig('ax1.png')

f2 = plt.figure()
ax2 = f2.add_axes([0.2, 0.2, 0.6, 0.6])
ax2.axis([0, 1000, 0, 1000])
plt.savefig('ax2.png')

You can find more info about it here:
http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.add_axes

你可以在这里找到更多的信息:http://matplotlib.org/api/figure_api.html#matplotlib. figure.add_axes。

Edit: You can achieve a similar result using subplots_adjust. Using your example code:

编辑:您可以使用subplots_调整实现类似的结果。使用你的示例代码:

fig = plt.figure(1)
ax = fig.add_subplot(111)
fig.tight_layout()
plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8)

#1


1  

This is how I usually setup my code if I want to have a fine control over the size of the figure's margins in matplotlib. In addition, I show how the position of the ylabel can be setup, so you can easily align the ylabels of your two figures together.

这是我通常设置我的代码的方式,如果我想在matplotlib中对图的边缘的大小有一个精确的控制。此外,我还展示了ylabel的位置是如何设置的,所以您可以轻松地将两个数据的ylabel组合在一起。

import matplotlib.pyplot as plt

plt.close('all')

#---- create figure ----

fwidth = 8.  # total width of the figure in inches
fheight = 4. # total height of the figure in inches

fig = plt.figure(figsize=(fwidth, fheight))

#---- define margins -> size in inches / figure dimension ----

left_margin  = 0.95 / fwidth
right_margin = 0.2 / fwidth
bottom_margin = 0.5 / fheight
top_margin = 0.25 / fheight

#---- create axes ----

# dimensions are calculated relative to the figure size

x = left_margin    # horiz. position of bottom-left corner
y = bottom_margin  # vert. position of bottom-left corner
w = 1 - (left_margin + right_margin) # width of axes
h = 1 - (bottom_margin + top_margin) # height of axes

ax = fig.add_axes([x, y, w, h])

#---- Define the Ylabel position ----

# Location are defined in dimension relative to the figure size  

xloc =  0.25 / fwidth 
yloc =  y + h / 2.  

ax.set_ylabel('yLabel', fontsize=16, verticalalignment='top',
              horizontalalignment='center')             
ax.yaxis.set_label_coords(xloc, yloc, transform = fig.transFigure)

plt.show(block=False)
fig.savefig('figure_margins.png')

This results in a 8in x 4in figure, with margins of exactly 0.95, 0.2, 0.5, and 0.25 inch at the left, right, bottom and top of the figure. One benefit of this approach is that the size of the margins are defined in absolute units (inches), meaning they will remain consistent even if you change the size of the figure.

这导致了一个8in x 4in的数字,在左边,右边,底部和顶部的边缘正好是0.95,0.2,0.5,和0.25英寸。这种方法的一个好处是,边缘的大小是用绝对单位(英寸)来定义的,这意味着即使你改变了图形的大小,它们也会保持一致。

As for the ylabel, horizontally, the top of the label is located 0.25 inch from the left edge of the figure, while vertically the centre of the label corresponds to the centre of the axe. Note that due to the 90 degrees rotation on the ylabel, the meaning of the verticalalignment and horizontalalignment are in reality inverted.

至于ylabel,水平上,标签的顶部距离图形的左边缘0.25英寸,而垂直的标签的中心对应于斧头的中心。注意,由于ylabel上的90度旋转,垂直对齐和水平对齐的意义在现实中颠倒了。

Below are shown outputs of the code above with the yaxis limits set to [0, 1] and to [0, 18] respectively.

下面显示的是上述代码的输出,它们分别设置为[0,1]和[0,18]。

Matplotlib:图形左边缘与y轴之间的固定间距。 Matplotlib:图形左边缘与y轴之间的固定间距。

#2


3  

I think you can set this property (space between edge of figure and axis) when you create the axes (add_axes to a figure object). Here is some simple example code that produces two axes with generous spacing on all sides:

我认为,当您创建坐标轴(add_axes到一个图形对象)时,您可以设置这个属性(图和轴的边缘之间的空间)。下面是一些简单的示例代码,它产生了两个轴,它们的间距都很宽:

import matplotlib.pyplot as plt

f1 = plt.figure()
ax1 = f1.add_axes([0.2, 0.2, 0.6, 0.6]) # List is [left, bottom, width, height]
ax1.axis([0, 1, 0, 1])
plt.savefig('ax1.png')

f2 = plt.figure()
ax2 = f2.add_axes([0.2, 0.2, 0.6, 0.6])
ax2.axis([0, 1000, 0, 1000])
plt.savefig('ax2.png')

You can find more info about it here:
http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.add_axes

你可以在这里找到更多的信息:http://matplotlib.org/api/figure_api.html#matplotlib. figure.add_axes。

Edit: You can achieve a similar result using subplots_adjust. Using your example code:

编辑:您可以使用subplots_调整实现类似的结果。使用你的示例代码:

fig = plt.figure(1)
ax = fig.add_subplot(111)
fig.tight_layout()
plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8)