Description
Most use of matplotlib
througout the package rely on the implicit pyplot
API.
I'd advocate for using the more explicit OOP-oriented API since it is considered cleaner, more pythonic, and allows for more control over plots.
The difference between the 2 APIs is described here : https://matplotlib.org/stable/users/explain/figure/api_interfaces.html
Example for distributions
For example, in the base class for distributions, the view
method :
optiland/optiland/distribution.py
Line 58 in 6530b81
uses plt
for accessing matplotlib
. This code could be replace with, for example :
Before
def view(self):
"""Visualize the distribution.
This method plots the distribution points and a unit circle for
reference.
"""
plt.plot(self.x, self.y, "k*")
t = np.linspace(0, 2 * np.pi, 256)
x, y = np.cos(t), np.sin(t)
plt.plot(x, y, "r")
plt.xlabel("Normalized Pupil Coordinate X")
plt.ylabel("Normalized Pupil Coordinate Y")
plt.axis("equal")
plt.show()
After
def view(self, ax=None):
"""Visualize the distribution.
This method plots the distribution points and a unit circle for
reference.
"""
if ax is None:
fig, ax = plt.subplots()
ax.plot(self.x, self.y, "k*")
t = np.linspace(0, 2 * np.pi, 256)
x, y = np.cos(t), np.sin(t)
ax.plot(x, y, "r")
ax.set_xlabel("Normalized Pupil Coordinate X")
ax.set_ylabel("Normalized Pupil Coordinate Y")
ax.set_aspect("equal")
return ax
This way :
- the user can either provide the
Axes
or let the method just create a new one with signature(self, ax=None):
- and return the
Axes
for further customization withreturn ax
- and delay the actual displaying by removing
plt.show()
Generalization
This approach could (and should?) be applied throughout all plottings with matplotlib
in the package:
Line 107 in 6530b81
optiland/optiland/wavefront.py
Line 421 in 6530b81
Note on circles
I believe using
circle = plt.Circle((xc, yc), R, fill=False)
ax.add_patch(circle)
is considered a cleaner approach to plot a circle on an ax (removes the need for sampling `t = np.linspace(0, 2 * np.pi, 256)' )