Plot typography affects whether titles, axis labels, and tick values stay readable after a figure leaves Python. In Matplotlib, font settings can be controlled through rcParams so every text object in a script starts from the same family and size choices.

Runtime rcParams are a reversible project-level layer because they apply only to the current Python process. Matplotlib tries font families in list order, using generic aliases such as serif or sans-serif as fallback groups when an exact family is not available.

DejaVu Serif is used here because Matplotlib includes DejaVu fonts with common installations. The saved PNG plus the resolved TTF filename confirm that the family list, fallback behavior, and font sizes reached the rendered plot.

Steps to configure Matplotlib fonts:

  1. Save the font configuration script as font_configure.py.
    font_configure.py
    from pathlib import Path
     
    import matplotlib
    from matplotlib import font_manager
    import matplotlib.pyplot as plt
     
     
    plt.rcParams.update(
        {
            "font.family": ["DejaVu Serif", "serif"],
            "font.size": 12,
            "axes.titlesize": 15,
            "axes.labelsize": 12,
            "xtick.labelsize": 10,
            "ytick.labelsize": 10,
        }
    )
     
    requested_family = plt.rcParams["font.family"]
    resolved_font = font_manager.findfont(
        font_manager.FontProperties(family=requested_family),
        fallback_to_default=False,
    )
     
    quarters = ["Q1", "Q2", "Q3", "Q4"]
    satisfaction = [82, 86, 88, 91]
     
    fig, ax = plt.subplots(figsize=(6.4, 3.8), layout="constrained")
    ax.plot(quarters, satisfaction, marker="o", linewidth=2.2, color="#3E6C9A")
    title = ax.set_title("Customer satisfaction trend", fontweight="bold")
    xlabel = ax.set_xlabel("Quarter")
    ylabel = ax.set_ylabel("Score")
    ax.grid(True, axis="y", alpha=0.25)
     
    output = Path("font-configure.png")
    fig.savefig(output, dpi=160)
    plt.close(fig)
     
    print(f"matplotlib {matplotlib.__version__} ({matplotlib.get_backend()} backend)")
    print(f"font family: {requested_family}")
    print(f"resolved font: {Path(resolved_font).name}")
    print(f"title font: {title.get_fontfamily()} {title.get_fontsize():.0f} pt")
    print(f"x label font: {xlabel.get_fontfamily()} {xlabel.get_fontsize():.0f} pt")
    print(f"y label font: {ylabel.get_fontfamily()} {ylabel.get_fontsize():.0f} pt")
    print(f"saved: {output}")
    print(f"bytes: {output.stat().st_size}")

    fallback_to_default=False makes the script fail if the family list cannot resolve to a real font file. Keep a generic family such as serif or sans-serif at the end of the list when replacing DejaVu Serif with a local font.

  2. Run the script from the directory where the figure should be saved.
    $ python font_configure.py
    matplotlib 3.11.0 (Agg backend)
    font family: ['DejaVu Serif', 'serif']
    resolved font: DejaVuSerif.ttf
    title font: ['DejaVu Serif', 'serif'] 15 pt
    x label font: ['DejaVu Serif', 'serif'] 12 pt
    y label font: ['DejaVu Serif', 'serif'] 12 pt
    saved: font-configure.png
    bytes: 39466

    The byte count can change with Matplotlib, backend, DPI, and font rendering differences. The resolved font line and text-object sizes confirm that the configured family and sizes were used before the file was written.

  3. Open font-configure.png and confirm that the exported plot uses the configured serif font.

    The title, tick labels, and axis labels should use a serif face, with the title larger than the axis labels.

  4. Replace the family list and sizes for your project.
    plt.rcParams.update(
        {
            "font.family": ["Source Sans 3", "DejaVu Sans", "sans-serif"],
            "font.size": 11,
            "axes.titlesize": 13,
            "axes.labelsize": 11,
        }
    )

    Use font_manager.get_font_names() to inspect installed family names. For non-Latin text, put a font with the required glyphs first and keep a generic family at the end as a fallback.

  5. Remove the sample files when they were created only for testing.
    $ rm font_configure.py font-configure.png