8000 [Bug]: Rendering inconsistency between matplotlib-inline `plt.show()` and `fig.savefig(...)` · Issue #24281 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content
[Bug]: Rendering inconsistency between matplotlib-inline plt.show() and fig.savefig(...) #24281
Closed as not planned
@posita

Description

@posita

Bug summary

This originally came up in jupyterlite/jupyterlite#850, but I'm pretty sure the root cause is here. I'll reproduce the most helpful comment from that thread here. The following is a pretty good demonstration of how savefig clips (e.g.) the title of a pie chart.

Possibly related issues:

Code for reproduction

Run the following in Jupyter Lab to reproduce the attached images.

import matplotlib.pyplot
import base64, io
from enum import Enum
from ipywidgets import widgets
from fractions import Fraction
from itertools import chain

data = {3: Fraction(1, 216), 4: Fraction(1, 72), 5: Fraction(1, 36), 6: Fraction(5, 108), 7: Fraction(5, 72), 8: Fraction(7, 72), 9: Fraction(25, 216), 10: Fraction(1, 8), 11: Fraction(1, 8), 12: Fraction(25, 216), 13: Fraction(7, 72), 14: Fraction(5, 72), 15: Fraction(5, 108), 16: Fraction(1, 36), 17: Fraction(1, 72), 18: Fraction(1, 216)}

class Format(str, Enum):
    NATIVE = "native"
    PNG = "png"
    SVG = "svg"

class PngImage:
    def __init__(self, data):
        self.data = data

    def _repr_png_(self):
        return base64.b64encode(self.data).decode()

class SvgImage:
    def __init__(self, data):
        self.data = data

    def _repr_svg_(self):
        return self.data.decode()

@widgets.interact
def show(output_to_format = Format, use_subplots: bool = True):
    with matplotlib.style.context("bmh"):
        if use_subplots:
            _, ax = matplotlib.pyplot.subplots()
        else:
            fig = matplotlib.pyplot.figure()
            xmin, ymin, dx, dy = 0.1, 0.1, 0.9, 0.9
            ax = fig.add_axes((xmin, ymin, dx, dy))
        unique_outcomes = sorted(data.keys())
        ax.set_title(
            "Super duper duper long title that will probably exceed the width of the pie chart",
            fontdict={"fontweight": "bold",},
        )
        outcomes, values = zip(*((outcome, float(value)) for outcome, value in data.items()))
        ax.pie(outcomes, values)
        if output_to_format is Format.NATIVE:
            matplotlib.pyplot.show()
        else:
            buf = io.BytesIO()
            matplotlib.pyplot.savefig(buf, format=output_to_format)
            if output_to_format is Format.PNG:
                display(PngImage(buf.getvalue()))
            elif output_to_format is Format.SVG:
                display(SvgImage(buf.getvalue()))
            else:
                assert False, "should never be here"
            matplotlib.pyplot.clf()

print(matplotlib.__version__)

Actual outcome

Output method Using subplots Using add_axes
show() native-subplots native-manual-axes
savefig(..., format="png") png-subplots png-manual-axes
savefig(..., format="svg") svg-subplots svg-manual-axes

Expected outcome

I expected all backends to produce at least similar results (i.e., not ones where titles were clipped or missing entirely).

Additional information

No response

Operating system

No response

Matplotlib Version

3.5.2, 3.6.1

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.10.6

Jupyter version

Lab 3.4.8

Installation

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0