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:
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
which really doesn't look right
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.
MatPlotLib with Python To change the range of X and Y axes, we can use xlim() and ylim() methods.
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').
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()
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()
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))
I used info from these answers:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With