Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib - fixing x axis scale and autoscale y axis

I would like to plot only part of the array, fixing x part, but letting y part autoscale. I tried as shown below, but it does not work.

Any suggestions?

import numpy as np import matplotlib.pyplot as plt  data=[np.arange(0,101,1),300-0.1*np.arange(0,101,1)]  plt.figure()  plt.scatter(data[0], data[1]) plt.xlim([50,100]) plt.autoscale(enable=True, axis='y')  plt.show() 

enter image description here

like image 224
Pygmalion Avatar asked Apr 05 '15 19:04

Pygmalion


People also ask

How do I make X and Y-axis scales the same in Matplotlib?

MatPlotLib with Python To change the range of X and Y axes, we can use xlim() and ylim() methods.

How do you change y-axis to log scale in Matplotlib?

pyplot library can be used to change the y-axis scale to logarithmic. The method yscale() takes a single value as a parameter which is the type of conversion of the scale, to convert y-axes to logarithmic scale we pass the “log” keyword or the matplotlib. scale. LogScale class to the yscale method.

How do you autoscale a plot in Python?

It turns autoscaling on or off, and then, if autoscaling for either axis is on, it performs the autoscaling on the specified axis or axes. Parameters: enable : bool or None, optional. True (default) turns autoscaling on, False turns it off.


2 Answers

While Joe Kington certainly proposes the most sensible answer when he recommends that only the necessary data be plotted, there are situations where it would be best to plot all of the data and just zoom to a certain section. Additionally, it would be nice to have an "autoscale_y" function that only requires the axes object (i.e., unlike the answer here, which requires direct use of the data.)

Here is a function that just rescales the y-axis based on the data that is in the visible x-region:

def autoscale_y(ax,margin=0.1):     """This function rescales the y-axis based on the data that is visible given the current xlim of the axis.     ax -- a matplotlib axes object     margin -- the fraction of the total height of the y-data to pad the upper and lower ylims"""      import numpy as np      def get_bottom_top(line):         xd = line.get_xdata()         yd = line.get_ydata()         lo,hi = ax.get_xlim()         y_displayed = yd[((xd>lo) & (xd<hi))]         h = np.max(y_displayed) - np.min(y_displayed)         bot = np.min(y_displayed)-margin*h         top = np.max(y_displayed)+margin*h         return bot,top      lines = ax.get_lines()     bot,top = np.inf, -np.inf      for line in lines:         new_bot, new_top = get_bottom_top(line)         if new_bot < bot: bot = new_bot         if new_top > top: top = new_top      ax.set_ylim(bot,top) 

This is something of a hack, and will probably not work in many situations, but for a simple plot, it works well.

Here is a simple example using this function:

import numpy as np import matplotlib.pyplot as plt  x = np.linspace(-100,100,1000) y = x**2 + np.cos(x)*100  fig,axs = plt.subplots(1,2,figsize=(8,5))  for ax in axs:     ax.plot(x,y)     ax.plot(x,y*2)     ax.plot(x,y*10)     ax.set_xlim(-10,10)  autoscale_y(axs[1])  axs[0].set_title('Rescaled x-axis') axs[1].set_title('Rescaled x-axis\nand used "autoscale_y"')  plt.show() 

enter image description here

like image 121
DanHickstein Avatar answered Oct 12 '22 12:10

DanHickstein


Autoscaling always uses the full range of the data, so the y-axis is scaled by full extent of the y-data, not just what's within the x-limits.

If you'd like to display a subset of the data, then it's probably easiest to plot only that subset:

import numpy as np import matplotlib.pyplot as plt  x, y = np.arange(0,101,1) ,300 - 0.1*np.arange(0,101,1) mask = (x >= 50) & (x <= 100)  fig, ax = plt.subplots() ax.scatter(x[mask], y[mask])  plt.show() 

enter image description here

like image 28
Joe Kington Avatar answered Oct 12 '22 13:10

Joe Kington