简体   繁体   中英

Matplotlib: fixed spacing between left edge of figure and y-axis

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.

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. 在此处输入图片说明

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

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 ?

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.

NOTE 2: I create my plot using:

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

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:

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

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

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)

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.

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.

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.

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

在此处输入图片说明 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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