attoworld.plot

This module will contain functions for plotting, and for formatting plots, with the goal of more easily obtaining a consistent style across plots made by different co-authors.

1"""
2This module will contain functions for plotting, and for formatting plots, with the goal of
3more easily obtaining a consistent style across plots made by different co-authors.
4"""
5
6from .plot import showmo, set_style, label_letter, Char
7
8__all__ = ["showmo", "set_style", "label_letter", "Char"]
def showmo():
10def showmo():
11    """
12    Helper function to plot as an svg to have vector plots in marimo notebooks
13    """
14    svg_buffer = io.StringIO()
15    plt.savefig(svg_buffer, format="svg")
16    return mo.output.append(mo.Html(svg_buffer.getvalue()))

Helper function to plot as an svg to have vector plots in marimo notebooks

def set_style(theme: str = 'light', font_size: int = 11):
 19def set_style(theme: str = "light", font_size: int = 11):
 20    """
 21    Set colors and fonts for matplotlib plots
 22
 23    Args:
 24        mode (str): Select color theme.
 25                    Options:
 26                        ```light```: color-blind friendly colors (default)
 27                        ```nick_dark```: dark mode that matches Nick's slides
 28    """
 29    plt.rcParams.update(
 30        {
 31            "font.size": font_size,
 32            "xtick.labelsize": 0.9 * font_size,
 33            "ytick.labelsize": 0.9 * font_size,
 34            "legend.fontsize": 0.9 * font_size,
 35            "figure.autolayout": True,
 36        }
 37    )
 38    match theme:
 39        case "nick_dark":
 40            plt.rcParams.update(
 41                {
 42                    "font.sans-serif": [
 43                        "Helvetica",
 44                        "Nimbus Sans L",
 45                        "Arial",
 46                        "Verdana",
 47                        "Nimbus Sans L",
 48                        "DejaVu Sans",
 49                        "Liberation Sans",
 50                        "Bitstream Vera Sans",
 51                        "sans-serif",
 52                    ],
 53                    "font.family": "sans-serif",
 54                    "axes.prop_cycle": cycler(
 55                        color=["cyan", "magenta", "orange", "blueviolet", "lime"]
 56                    ),
 57                    "figure.facecolor": "#171717",
 58                    "figure.edgecolor": "#171717",
 59                    "savefig.facecolor": "#171717",
 60                    "savefig.edgecolor": "#171717",
 61                    "axes.facecolor": "black",
 62                    "text.color": "white",
 63                    "axes.edgecolor": "white",
 64                    "axes.labelcolor": "white",
 65                    "xtick.color": "white",
 66                    "ytick.color": "white",
 67                    "grid.color": "white",
 68                    "lines.color": "white",
 69                    "image.cmap": "magma",
 70                }
 71            )
 72        # Light case is combined with _, which will capture anything else that didn't match.
 73        # It must be the last case, for that reason.
 74        case "light" | _:
 75            plt.rcParams.update(
 76                {
 77                    "font.sans-serif": [
 78                        "Helvetica",
 79                        "Nimbus Sans L",
 80                        "Arial",
 81                        "Verdana",
 82                        "DejaVu Sans",
 83                        "Liberation Sans",
 84                        "Bitstream Vera Sans",
 85                        "sans-serif",
 86                    ],
 87                    "font.family": "sans-serif",
 88                    # colorblind-friendly color cycle from https://gist.github.com/thriveth/8560036
 89                    "axes.prop_cycle": cycler(
 90                        color=[
 91                            "#377eb8",
 92                            "#ff7f00",
 93                            "#4daf4a",
 94                            "#f781bf",
 95                            "#a65628",
 96                            "#984ea3",
 97                            "#999999",
 98                            "#e41a1c",
 99                            "#dede00",
100                        ]
101                    ),
102                    "figure.facecolor": "white",
103                    "figure.edgecolor": "white",
104                    "savefig.facecolor": "white",
105                    "savefig.edgecolor": "white",
106                    "axes.facecolor": "white",
107                    "text.color": "black",
108                    "axes.edgecolor": "black",
109                    "axes.labelcolor": "black",
110                    "xtick.color": "black",
111                    "ytick.color": "black",
112                    "grid.color": "black",
113                    "lines.color": "black",
114                    "image.cmap": "viridis",
115                }
116            )

Set colors and fonts for matplotlib plots

Arguments:
  • mode (str): Select color theme. Options: light: color-blind friendly colors (default) nick_dark: dark mode that matches Nick's slides
def label_letter( letter: str = 'a', axis: matplotlib.axes._axes.Axes = <Axes: >, style: str = 'Nature', x_position: float = -0.14, y_position: float = 1.08):
119def label_letter(
120    letter: str = "a",
121    axis: Axes = plt.gca(),
122    style: str = "Nature",
123    x_position: float = -0.14,
124    y_position: float = 1.08,
125):
126    """
127    Put a letter in the corner of a set of axes to label them
128
129    Args:
130        axis: The axes to use (default is current ones)
131        letter (str): The letter to use
132        style (str): The journal style to apply. Options are ```Nature```, ```Science```, and ```OSA```
133        x_position (float): where to put the label horizontally relative to the axes of the figure
134        y_position (float): vertical position
135
136    """
137    letter_string = f"{letter}"
138    fontweight = "normal"
139    match style:
140        case "Nature":
141            letter_string = letter_string.lower()
142            fontweight = "bold"
143        case "Science":
144            letter_string = letter_string.upper()
145            fontweight = "bold"
146        case "OSA":
147            letter_string = "(" + letter_string.lower() + ")"
148            fontweight = "bold"
149
150    axis.text(
151        x_position,
152        y_position,
153        letter_string,
154        ha="center",
155        transform=axis.transAxes,
156        fontweight=fontweight,
157    )

Put a letter in the corner of a set of axes to label them

Arguments:
  • axis: The axes to use (default is current ones)
  • letter (str): The letter to use
  • style (str): The journal style to apply. Options are Nature, Science, and OSA
  • x_position (float): where to put the label horizontally relative to the axes of the figure
  • y_position (float): vertical position
@dataclass
class Char:
160@dataclass
161class Char:
162    """
163    Contains useful characters and strings for plot labels.
164
165    Examples:
166        >>> plt.xlabel(aw.plot.Char.wavelength_micron)
167        >>> plt.ylabel(f'{aw.plot.Char.theta} ({aw.plot.Char.degrees})')
168    """
169
170    mu: str = "\u03bc"
171    phi: str = "\u03a6"
172    lam: str = "\u03bb"
173    theta: str = "\u03b8"
174    micron: str = "\u03bcm"
175    degrees: str = "\u00b0"
176    angstrom: str = "\u212b"
177    wavelength_micron: str = "Wavelength (\u03bcm)"
178    energy_microjoule: str = "Energy (\u03bcJ)"

Contains useful characters and strings for plot labels.

Examples:
>>> plt.xlabel(aw.plot.Char.wavelength_micron)
>>> plt.ylabel(f'{aw.plot.Char.theta} ({aw.plot.Char.degrees})')
Char( mu: str = 'μ', phi: str = 'Φ', lam: str = 'λ', theta: str = 'θ', micron: str = 'μm', degrees: str = '°', angstrom: str = 'Å', wavelength_micron: str = 'Wavelength (μm)', energy_microjoule: str = 'Energy (μJ)')
mu: str = 'μ'
phi: str = 'Φ'
lam: str = 'λ'
theta: str = 'θ'
micron: str = 'μm'
degrees: str = '°'
angstrom: str = 'Å'
wavelength_micron: str = 'Wavelength (μm)'
energy_microjoule: str = 'Energy (μJ)'