Bug summary
Pickle round-tripping a figure incorrectly restores its original DPI instead of a DPI explicitly changed via Figure.set_dpi().
Code for reproduction
import pickle
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(5, 3), dpi=100)
ax.plot([0, 1, 2, 3], [0, 1, 4, 9], label="quadratic")
ax.set_title("DPI round trip")
ax.legend()
print("Original DPI:", fig.get_dpi())
fig.set_dpi(150)
print("DPI after public set_dpi(150):", fig.get_dpi())
restored = pickle.loads(pickle.dumps(fig))
print("DPI after pickle round trip:", restored.get_dpi())
print("Line count:", len(restored.axes[0].lines))
plt.close(fig)
plt.close(restored)
Actual outcome
Original DPI: 100
DPI after public set_dpi(150): 150
DPI after pickle round trip: 100
Line count: 1
Expected outcome
The explicitly configured DPI should be preserved across pickle round-tripping:
Original DPI: 100
DPI after public set_dpi(150): 150
DPI after pickle round trip: 150
Line count: 1
Additional information
This regression was introduced by PR #23476.
The new code replaces the current DPI with _original_dpi whenever that state entry exists. This correctly discards a transient DPI change made for a canvas device-pixel ratio, but _original_dpi is established independently of later public calls to Figure.set_dpi(). Consequently, a figure intentionally changed from 100 to 150 DPI is serialized with 100 DPI instead of 150 DPI, causing a loss of public figure state.
Operating system
Linux
Matplotlib Version
3.11.0
Matplotlib Backend
agg
Python version
3.11.13
Jupyter version
N/A
Installation
N/A
Bug summary
Pickle round-tripping a figure incorrectly restores its original DPI instead of a DPI explicitly changed via
Figure.set_dpi().Code for reproduction
Actual outcome
Expected outcome
The explicitly configured DPI should be preserved across pickle round-tripping:
Additional information
This regression was introduced by PR #23476.
The new code replaces the current DPI with
_original_dpiwhenever that state entry exists. This correctly discards a transient DPI change made for a canvas device-pixel ratio, but_original_dpiis established independently of later public calls toFigure.set_dpi(). Consequently, a figure intentionally changed from 100 to 150 DPI is serialized with 100 DPI instead of 150 DPI, causing a loss of public figure state.Operating system
Linux
Matplotlib Version
3.11.0
Matplotlib Backend
agg
Python version
3.11.13
Jupyter version
N/A
Installation
N/A