How to align xticks of multiple subplot vertically?

Question:

When I try to plot 3 subplots from a specific rows of a dataframe I get a weird result that the third subplot has a different spacing in the xticks even though the start of the plot seems to be correct.
I presume it could have something to do with the datasince FE 57 and FE 59 both start at an index close to 0 and FE 66 stars at an index at 3600.
Is there a way to plot all with white space starting from 0 so that all the xticks align vertically with each other?

fig, axs = plt.subplots(3, 1)
ser = plotdf[(plotdf['CAN_address'] == 'FE 57') & (plotdf['CAN_cmd'] == 62)]['CAN_value_translated']
axs[0].plot(ser.index, ser.values)
axs[0].set_title('FE 57')

ser = plotdf[(plotdf['CAN_address'] == 'FE 59') & (plotdf['CAN_cmd'] == 62)]['CAN_value_translated']
axs[1].plot(ser.index, ser.values)
axs[1].set_title('FE 59')

ser = plotdf[(plotdf['CAN_address'] == 'FE 66') & (plotdf['CAN_cmd'] == 62)]['CAN_value_translated']
axs[2].plot(ser.index, ser.values)
axs[2].set_title('FE 66')

plt.show()

moved xticks in the last plot

Asked By: Anjo

||

Answers:

You can set the limits of you axes with set_xlim():

x_min = -1000
x_max = 51000

for ax in axs:
  ax.set_xlim((x_min, x_max))
Answered By: Tranbi

To align the x-ticks of multiple subplots vertically, you can first set the xlim of all the subplots to the same values so that they all show the same range of x-values. Then, you can use the set_xticks method of each subplot to specify the locations of the x-ticks.

# Set the x-limits of all subplots to be the same
max_x = 3600

for ax in axs:
    ax.set_xlim((0, max_x))

# Set the number of x-ticks
num_xticks = 10

# Calculate the interval between x-ticks
interval = max_x // num_xticks

# Generate an array of x-tick values
xticks = range(0, max_x+1, interval)

# Set the x-ticks of all subplots to be the same
for ax in axs:
    ax.set_xticks(xticks)
Answered By: Lumo

enter image description here

You should instantiate the subplots using the keyword argument sharex=....
You can specify the value as 'all', 'row', 'col', 'none', that make sense if you think of a 2D arrangement of subplots.
I said "you should" and not "you must" because sharing the x-axis places the x tick labels only on the bottom subplot, and you may disagree with that.

The image above was generated as

import matplotlib.pyplot as plt

fig, (ax0, ax1) = plt.subplots(nrows=2, sharex='col')

ax0.plot((0, 7),(1, 12))
ax1.plot((-7,0),(1, -2))
plt.show()

If you don’t like the labels only on the bottom, you can do like this (image below)

fig, (ax0, ax1, ax2) = plt.subplots(nrows=3)

ax0.plot((0, 7),(1, 12))
ax1.plot((-7,0),(1, -2))
ax2.plot((-3,5),(-5,10))

# collect the lower and upper bounds of the x-axes
xmins, xmaxs = zip(*(ax.get_xlim() for ax in (ax0, ax1, ax2)))

# .set_xlim accepts a tuple, that we compute here
xlim = (min(xmins), max(xmaxs))

# finally, we set the same xlim on all the x-axes
for ax in (ax0, ax1, ax2):
    ax.set_xlim(xlim)

plt.show()

enter image description here

PS if the y-data on the plots is "the same", I’d recommend that you use also sharey=..., so that the comparison between different instances is immediate (even better, plot the y-data in the same subplot).

Answered By: gboffi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.