Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Description
Problem
I find the syntax of pyplot a bit difficult to remember, and I have been thinking for a while about a way of making it friendlier taking advantage of Python tools. After some years of on/off iteration, I converged to what I think is a really nice interface. In very brief, I use:
- A dataclass for all the setup (figure size, labels, ticks, grid, whether to save/show the figure...)
- A context manager to plot, and then do what I call "postprocessing" (color lines, create legend, adjust boundaries, show figure, save figure to a file...) automatically when the plot goes out of scope.
This is a (rather complete) example script, and the figure it generates:
importnastro.graphicsasngimportnumpyasnpif__name__=="__main__":# Generate datax=np.linspace(0,2*np.pi,100)y=np.sin(x)z=np.cos(x)error=np.abs(np.random.normal(0.0,0.1,x.shape))xbar=np.arange(8)ybar=np.random.normal(5,2,8)gen=np.random.default_rng(1234797)# Figure configurationfigure_setup=ng.PlotSetup(canvas_size=(12,7),title="A simple figure with different types of subplots",save=True,dir=".",name="plots.png",show=False, )a_setup=ng.PlotSetup(ylabel="left",rlabel="right",plabel="parasite")c_setup=ng.PlotSetup(grid=False)d_setup=ng.PlotSetup(ylabel="sin(x)",rlabel="cos(x)")withng.Mosaic("ab;cd;ef",figure_setup)asfig:withfig.subplot(a_setup,ng.ParasiteAxis)asa:a.line(x,x,fmt=".-",markersize=2,label="x")a.line(x,x**2,fmt="--",axis="right",label="x^2")a.line(x,x**3,axis="parasite",label="x^3")withfig.subplot(generator=ng.SingleAxis)asb:b.line(x,y,label="sin")b.line(x,z,label="cos")b.boundary(0.5,reference="sin")b.boundary(0.25,reference="sin",alpha=0.3)withfig.subplot(c_setup)asc:c.bar(xbar,ybar)withfig.subplot(d_setup,ng.DoubleAxis)asd:d.errorbar(x,y,np.abs(gen.normal(0.0,0.1,x.shape)))d.errorbar(x,z,np.abs(gen.normal(0.0,0.1,x.shape)),axis="right" )d.line(x,0.8*y)withfig.subplot(generator=ng.DoubleAxis)ase:e.step(x,y,fmt=".-")e.step(x,z,axis="right")withfig.subplot()asf:f.barh(xbar[:4],ybar[:4])
This interface was born as a submodule of a library I was writing for astrodynamics, but I have been using it for general plotting for about a year now, and it seems flexible and robust. I don't think I have the technical knowledge, or the time to add this to matplotlib, but maybe someone here does.
All my source code is open, and I'd be happy to discuss the details of my implementation, or to improve the description of this issue if you are interested :)
Proposed solution
No response