Home > Enterprise >  How to keep the pyplot axis scaled according to one plot only and not extending for other plots?
How to keep the pyplot axis scaled according to one plot only and not extending for other plots?

Time:04-19

I want to plot several functions in one figure, but I want to prevent the axis to be extended if one function is plotted that has much higher/smaller values than others. In the code below, the parameter alpha is actually random (here I fixed it to alpha = 2), and could get very high values which messes up my plot. Basically what I would like to do is, I'd like to plot one function, then freeze the axis according to its xlim and ylim, then add the remaining plots without extending the axis anymore if alpha happens to be large. How can I do this? My plot This orange plot extends the axis such that the other plots are not interpretable anymore. I'd like the orange plot to to overshoot in the y-direction, like this: What I want but without setting ylim manually.

CodePudding user response:

If you want to adjust the y-axis to the maximum and minimum values ​​of data1, use the code below. (0.05 is padding.)

axsLeft.set_ylim(np.min(data1) - 0.05, np.max(data1)   0.05)

If you want the alpha value to also vary according to data1, you can get the value by subtracting the alpha value from np.max() and np.min(). Below is a modified version of the code you uploaded.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,4*np.pi)
data1 = np.sin(0.5*x)
alpha = np.max(data1) - np.min(data1) # change 1
data2 = alpha*np.sin(x)
data3 = np.sin(x)
data4 = np.sin(x)
data5 = np.cos(x)

fig = plt.figure(constrained_layout=True, figsize=(10, 4))
subfigs = fig.subfigures(1, 2, wspace=0.07)

axsLeft = subfigs[0].subplots(1, 1)
axsLeft.plot(x,data1)
axsLeft.plot(x,data2) #final prediction
axsLeft.plot(x,data3,'--k',linewidth=2.5)
axsLeft.set_xlabel("x")
axsRight = subfigs[1].subplots(2, 1, sharex=True)
axsRight[0].plot(data4)
axsRight[1].plot(data5)
axsLeft.set_ylim(-alpha / 2 - 0.05, alpha / 2   0.05) # change 2
axsRight[1].set_xlabel('x')

plt.show()

CodePudding user response:

After plotting the reference, in your case data1, you can retrieve the defined y-axis limits with get_ylim() in seperate variables a and b and rescale your axis accordingly after plotting the remaining curves with set_ylim:

This makes sure the axis is always scaled according to the reference and it works even if the lower limit of the y-axis is very low or zero.

import numpy as np
from matplotlib import pyplot as plt

x = np.linspace(0,4*np.pi)
data1 = np.sin(0.5*x)
alpha = 2
data2 = alpha*np.sin(x)
data3 = np.sin(x)
data4 = np.sin(x)
data5 = np.cos(x)

fig = plt.figure(constrained_layout=True, figsize=(10, 4))
subfigs = fig.subfigures(1, 2, wspace=0.07)


axsLeft = subfigs[0].subplots(1, 1)
# reference axis
axsLeft.plot(x,data1)
a,b = axsLeft.get_ylim()

axsLeft.plot(x,data2) #final prediction
axsLeft.plot(x,data3,'--k',linewidth=2.5)
axsLeft.set_xlabel("x")

# set limit according to reference
axsLeft.set_ylim((a,b))


axsRight = subfigs[1].subplots(2, 1, sharex=True)
axsRight[0].plot(data4)
axsRight[1].plot(data5)
axsRight[1].set_xlabel('x')

fig.show()
  • Related