A.Razavi
A.Razavi

Reputation: 509

How to automatically set the scale for x-axis to be equal for all subplots in matplotlib?

In this example:

import numpy as np
import matplotlib.pyplot as plt

t1 = np.linspace(0, 1, 1000)
t2 = np.linspace(0, 0.5, 1000)

plt.figure(figsize=(10,5))

plt.subplot(121)
plt.plot(t1, np.sin(t1 * np.pi))

plt.subplot(122)
plt.plot(t2, np.sin(t2 * np.pi))

plt.show()

enter image description here

How can I squeeze the size of the second plot so that the x-axis for both subplots would have the same scale?, so it would look something like this:

enter image description here

I am looking for a simple and automatic way to do this because I have more than 30 subplots and would want them all have the same x-axis scale.

Upvotes: 0

Views: 3238

Answers (4)

Mr. T
Mr. T

Reputation: 12410

You could approximate the same unit length on both x-axes by specifying the gridspec_kw parameter that defines the ratio of the subplots.

import numpy as np
from matplotlib import pyplot as plt

t1 = np.linspace(0, 1, 1000)
t2 = np.linspace(0, 0.5, 1000)

fig, (ax1, ax2) = plt.subplots(1, 2, gridspec_kw = {"width_ratios": [np.max(t1)-np.min(t1), np.max(t2)-np.min(t2)]})

ax1.plot(t1, np.sin(t1 * np.pi))
ax2.plot(t2, np.sin(t2 * np.pi))

plt.show()

Sample output:
enter image description here

Upvotes: 2

Bal Krishna Jha
Bal Krishna Jha

Reputation: 7206

You can achieve it by changing the aspect ratio:

import numpy as np
import matplotlib.pyplot as plt

t1 = np.linspace(0, 1, 1000)
t2 = np.linspace(0, 0.5, 1000)

plt.figure(figsize=(10,5))

fig,ax = plt.subplots(nrows = 1,ncols = 2)

ax[0].plot(t1, np.sin(t1 * np.pi))

x1,x2 =ax[1].get_xlim()
x_diff = x2-x1
y1,y2 = ax[1].get_ylim()
y_diff = y2-y1

#plt.subplot(122)
ax[1].plot(t2, np.sin(t2 * np.pi))
ax[1].set_aspect(y_diff/x_diff)

Output: enter image description here

Upvotes: 0

flome
flome

Reputation: 1

A presumably not very proper way of doing so but in my opinion useful for a work around would be the use of subplot2grid:

plt.subplot2grid((ROWS, COLS), (START_ROW, START_COL), rowspan=ROWSPAN, colspan=COLSPAN)

using this, you could create two subplots which add up to the desired length and passing the colspan accordingly to the length of your x axis like for example:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 5)
y = np.linspace(0, 10)

plt.figure(figsize=(10,5)) # as specified from your code

# x.max() + y.max() is the total length of your x axis
# this can then be split in the parts of the length x.max() and y.max() 
# the parts then should have the correct aspect ratio
ax1 = plt.subplot2grid((1, int(x.max()+y.max()), (0, 0), colspan=int(x.max()))
ax2 = plt.subplot2grid((1, int(x.max()+y.max()), (0, int(x.max())), colspan=int(y.max()))

ax1.plot(x, np.sin(x))
ax2.plot(y, np.sin(y))
plt.show()

The scales seem same for me, you would still have to adjust the xticklabels in case those are supposed to be same as well

Upvotes: 0

Frank
Frank

Reputation: 418

You can use plt.xlim(xmin, xmax) to set the domain of the graph. Using plt.xlim() without giving it parameters returns the current xmin/xmax of the plot. The same applies for plt.ylim().

Upvotes: 0

Related Questions