Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set axis ticks in multiples of pi (Python) (matplotlib)

I'd like to make a plot in Python and have x range display ticks in multiples of pi.

Is there a good way to do this, not manually?

I'm thinking of using matplotlib, but other options are fine.

EDIT 3: EL_DON's solution worked for me like this:

import matplotlib.ticker as tck import matplotlib.pyplot as plt import numpy as np  f,ax=plt.subplots(figsize=(20,10)) x=np.linspace(-10*np.pi, 10*np.pi,1000) y=np.sin(x)  ax.plot(x/np.pi,y)  ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\pi$')) ax.xaxis.set_major_locator(tck.MultipleLocator(base=1.0))  plt.style.use("ggplot")   plt.show() 

giving:

nice sine graph

EDIT 2 (solved in EDIT 3!): EL_DON's answer doesn't seem to work right for me:

import matplotlib.ticker as tck import matplotlib.pyplot as plt import numpy as np  f,ax=plt.subplots(figsize=(20,10)) x=np.linspace(-10*np.pi, 10*np.pi) y=np.sin(x)  ax.plot(x/np.pi,y)  ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\pi$')) ax.xaxis.set_major_locator(tck.MultipleLocator(base=1.0))  plt.style.use("ggplot")  plt.show() 

gives me

plot

which really doesn't look right

like image 628
Zubo Avatar asked Nov 16 '16 20:11

Zubo


People also ask

How do I change the number of ticks in MatPlotLib?

Locator_params() function that lets us change the tightness and number of ticks in the plots. This is made for customizing the subplots in matplotlib, where we need the ticks packed a little tighter and limited. So, we can use this function to control the number of ticks on the plots.

How do you change axis increments in Python?

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

How do I enable minor ticks in MatPlotLib?

MatPlotLib with Python Create a figure and a set of subplots. Plot x and y data points using plot() method. To locate minor ticks, use set_minor_locator() method. To show the minor ticks, use grid(which='minor').


2 Answers

This is inspired by Python Data Science Handbook, although Sage attempts to do without explicit parameters.

EDIT: I've generalized this to allow you to supply as optional parameters the denominator, the value of the unit, and the LaTeX label for the unit. A class definition is included if you find that helpful.

import numpy as np import matplotlib.pyplot as plt  def multiple_formatter(denominator=2, number=np.pi, latex='\pi'):     def gcd(a, b):         while b:             a, b = b, a%b         return a     def _multiple_formatter(x, pos):         den = denominator         num = np.int(np.rint(den*x/number))         com = gcd(num,den)         (num,den) = (int(num/com),int(den/com))         if den==1:             if num==0:                 return r'$0$'             if num==1:                 return r'$%s$'%latex             elif num==-1:                 return r'$-%s$'%latex             else:                 return r'$%s%s$'%(num,latex)         else:             if num==1:                 return r'$\frac{%s}{%s}$'%(latex,den)             elif num==-1:                 return r'$\frac{-%s}{%s}$'%(latex,den)             else:                 return r'$\frac{%s%s}{%s}$'%(num,latex,den)     return _multiple_formatter ​ class Multiple:     def __init__(self, denominator=2, number=np.pi, latex='\pi'):         self.denominator = denominator         self.number = number         self.latex = latex ​     def locator(self):         return plt.MultipleLocator(self.number / self.denominator) ​     def formatter(self):         return plt.FuncFormatter(multiple_formatter(self.denominator, self.number, self.latex)) 

This can be used very simply, without any parameters:

x = np.linspace(-np.pi, 3*np.pi,500) plt.plot(x, np.cos(x)) plt.title(r'Multiples of $\pi$') ax = plt.gca() ax.grid(True) ax.set_aspect(1.0) ax.axhline(0, color='black', lw=2) ax.axvline(0, color='black', lw=2) ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 12)) ax.xaxis.set_major_formatter(plt.FuncFormatter(multiple_formatter())) plt.show() 

plot of cos(x)

Or it can be used in a more sophisticated way:

tau = np.pi*2 den = 60 major = Multiple(den, tau, r'\tau') minor = Multiple(den*4, tau, r'\tau') x = np.linspace(-tau/60, tau*8/60,500) plt.plot(x, np.exp(-x)*np.cos(60*x)) plt.title(r'Multiples of $\tau$') ax = plt.gca() ax.grid(True) ax.axhline(0, color='black', lw=2) ax.axvline(0, color='black', lw=2) ax.xaxis.set_major_locator(major.locator()) ax.xaxis.set_minor_locator(minor.locator()) ax.xaxis.set_major_formatter(major.formatter()) plt.show() 

plot of exp(-x)*cos(60*x)

like image 135
Scott Centoni Avatar answered Sep 22 '22 09:09

Scott Centoni


f,ax=plt.subplots(1) x=linspace(0,3*pi,1001) y=sin(x) ax.plot(x/pi,y) ax.xaxis.set_major_formatter(FormatStrFormatter('%g $\pi$')) ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(base=1.0)) 

enter image description here

I used info from these answers:

  • https://stackoverflow.com/a/19972993/6605826
  • https://stackoverflow.com/a/29188910/6605826
like image 25
EL_DON Avatar answered Sep 18 '22 09:09

EL_DON