I am trying to make a plot which has two subplots which share the x axis and shall have no space in between them. I followd the Create adjacent subplots example from the matplotlib gallery. However, my plot needs to have a fixed size and this makes everything complicated. If I just follow the example and add a fixed size figure size, then the labels are cut off. If I include the labels by using tight_layout
, then the plots are spaced. How to fix this? Also, the title should be closer to the legend. Any help is much appreciated!
Example program, comment out tight_layout
to see the difference.
import numpy as np
import matplotlib.pyplot as plt
x_min = -2*np.pi
x_max = 2*np.pi
resolution = 101
x_vals = np.linspace(x_min, x_max, resolution)
y_upper = np.cos(x_vals)
y_lower = -np.cos(x_vals)
data3 = np.sin(x_vals)
fig = plt.figure(figsize=(80/25.4, 80/25.4)) # figsize is needed for later usage of the plot
ax = fig.subplots(2, 1, sharex=True)
fig.subplots_adjust(hspace=0)
ax[0].plot(x_vals, y_upper, label="data 1")
ax[0].plot(x_vals, y_lower, label="data 2")
ax[1].set_xlim([x_min,x_max])
ax[0].set_ylim([-1.6,1.6])
ax[1].set_ylim([-1.3,1.3])
ax[1].plot(x_vals, data3, ls='-', label="data 3", color='C2')
ax[1].set_xlabel("xaxis")
ax[0].set_ylabel("yaxis 1")
ax[1].set_ylabel("yaxis 2")
ax[0].legend(bbox_to_anchor=(0, 1.02, 1., 0.102), loc='lower left', ncol=2, mode="expand", borderaxespad=0)
fig.suptitle("Title")
fig.tight_layout() # comment this out to see the difference
# fig.savefig('figure.png')
plt.show()
You need to use a GridSpec
instead of subplots_adjust()
, that way tight_layout()
will know that you want zero-space and it keep it that way.
In fact, you are already creating a GridSpec
when you use fig.subplots()
, so you just need to pass some extra parameter in gridspec_kw=
x_min = -2*np.pi
x_max = 2*np.pi
resolution = 101
x_vals = np.linspace(x_min, x_max, resolution)
y_upper = np.cos(x_vals)
y_lower = -np.cos(x_vals)
data3 = np.sin(x_vals)
fig = plt.figure(figsize=(80/25.4, 80/25.4)) # figsize is needed for later usage of the plot
#
# This is the line that changes. Instruct the gridspec to have zero vertical pad
#
ax = fig.subplots(2, 1, sharex=True, gridspec_kw=dict(hspace=0))
ax[0].plot(x_vals, y_upper, label="data 1")
ax[0].plot(x_vals, y_lower, label="data 2")
ax[1].set_xlim([x_min,x_max])
ax[0].set_ylim([-1.6,1.6])
ax[1].set_ylim([-1.3,1.3])
ax[1].plot(x_vals, data3, ls='-', label="data 3", color='C2')
ax[1].set_xlabel("xaxis")
ax[0].set_ylabel("yaxis 1")
ax[1].set_ylabel("yaxis 2")
ax[0].legend(bbox_to_anchor=(0, 1.02, 1., 0.102), loc='lower left', ncol=2, mode="expand", borderaxespad=0)
fig.suptitle("Title")
fig.tight_layout() # Now tight_layout does not add padding between axes
# fig.savefig('figure.png')
plt.show()
It can be frustrating to get precise results with subplots - using gridspec ( https://matplotlib.org/3.3.3/tutorials/intermediate/gridspec.html ) will give your greater precision.
However, given where you are, I think you can get what you want with this:
import matplotlib.pyplot as plt
x_min = -2*np.pi
x_max = 2*np.pi
resolution = 101
x_vals = np.linspace(x_min, x_max, resolution)
y_upper = np.cos(x_vals)
y_lower = -np.cos(x_vals)
data3 = np.sin(x_vals)
fig = plt.figure(figsize=(80/25.4, 80/25.4)) # figsize is needed for later usage of the plot
ax = fig.subplots(3, 1, sharex=True)
fig.subplots_adjust(hspace=0)
ax[0].text(0,0.5,"Title", ha='center')
ax[0].axis("off")
ax[1].plot(x_vals, y_upper, label="data 1")
ax[1].plot(x_vals, y_lower, label="data 2")
ax[2].set_xlim([x_min,x_max])
ax[1].set_ylim([-1.6,1.6])
ax[2].set_ylim([-1.3,1.3])
ax[2].plot(x_vals, data3, ls='-', label="data 3", color='C2')
ax[2].set_xlabel("xaxis")
ax[1].set_ylabel("yaxis 1")
ax[2].set_ylabel("yaxis 2")
ax[1].legend(bbox_to_anchor=(0, 1.02, 1., 0.102), loc='lower left', ncol=2, mode="expand", borderaxespad=0)
#fig.tight_layout() # comment this out to see the difference
# fig.savefig('figure.png')
plt.show()
Of course, gridspec
is the correct approach, and if you are in early phases of the script writing, you should adapt this . However, if you want an easy fix, you could also move fig.subplots_adjust()
:
#...
fig.suptitle("Title")
fig.tight_layout()
fig.subplots_adjust(hspace=0)
# fig.savefig('figure.png')
plt.show()
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.