Repository navigation
Description
Bug summary
fig.set_dpi(150)only changes the dpi of plot shown in the Jupyter notebook but not in the saved figurefigure.dpiin thematplotlibrcfile does not work at all (EDIT: bug occurs inmatplotlib-inline 0.1.3but this is fixed inmatplotlib-inline 0.1.6)plt.subplots(dpi=150)works as expected and changes the dpi of both the plot shown in the Jupyter notebook as well as in the saved figure
Continuation of discussion in #11227
Code for reproduction
import matplotlib as mpl
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
fig.set_dpi(150)
ax.plot([1, 2], [1, 2])
print(fig.get_dpi())
print(mpl.rcParams["figure.dpi"])
print(mpl.rcParams["savefig.dpi"])
fig.savefig("test.png", dpi="figure")
plt.show()Actual outcome
Inside a Jupyter notebook running python 3.10.4 inside a conda environment (no matplotlibrc file):
150
72.0
figure
Inside a standalone Python script running the same python version inside a conda environment (no matplotlibrc file):
150
100.0
figure
Saved plot is at 100.0 dpi.
Expected outcome
-
fig.set_dpi(150)would set the dpi to 150 for the figure shown in the Jupyter notebook + the figure shown in the matplotlib window that pops up whenplt.show()is called as well as the figure saved. -
figure.dpiin thematplotlibrcfile would change the default dpi of figures created (but it does not). From my original comment in #11227:Moreover, I'm finding that on my machine, the
figure.dpircParam is not respected after I have modified it in mymatplotlibrcfile (located at~/.config/matplotlib/matplotlibrc). Other changes to options likeaxes.prop_cyclein mymatplotlibrcfile are being reflected in the plots shown in the Jupyter notebook as well as in those saved viafig.savefig(), but changes to thefigure.dpioption are not reflected in the plots shown/saved -
The default dpi should be 100.0 instead of 72.0 (only seems to happen inside Jupyter notebooks and not in standalone python scripts)
-
(similar to point #1)
fig.savefig("test.png", dpi="figure")should reflect the changed dpi that was set withfig.set_dpi(150). Instead, it saves the figure at 72.0 dpi (when running the code in a Jupyter notebook) or 100.0 dpi (when running the code in a standalone Python script). Both the Jupyter notebook and Python script are running the same Python version in the same conda environment.
Additional information
Previous discussion in #11227
Operating system
WSL2 running Ubuntu 20.04.5 LTS
Matplotlib Version
3.5.2
Matplotlib Backend
Inside Jupyter notebook (same regardless whether or not matplitlibrc file exists): module://matplotlib_inline.backend_inline.
Inside Python script with no matplotlibrc file: QtAgg
Inside Python script with matplotlibrc file: TkAgg (since I set my backend to TkAgg in my matplotlibrc file)
Python version
3.10.4
Jupyter version
6.5.2
Installation
conda 22.9.0

Activity
tacaswell commentedon Dec 7, 2022
Do you have a high-dpi screen?
BearBearCodes commentedon Dec 7, 2022
Yes I sometimes use a high dpi screen but I've noticed this behaviour even when I'm only using my laptop screen (1920×1080) with no external displays connected.
tacaswell commentedon Dec 7, 2022
The source of the problem is this:
dpi='figure'[3]Doing
fig, ax = plt.subplots(dpi=150)works as expected (because we set it early).mpl.rcParams['figure.dpi'] = 150should work, but you may have to updatematplotlib-inlineto get a version that does not change rcParams on import for it to work set viamatplotlibrc.[1]
matplotlib/lib/matplotlib/backend_bases.py
Lines 2117 to 2123 in b2e8434
[2]
matplotlib/lib/matplotlib/backend_bases.py
Line 1673 in b2e8434
[3]
matplotlib/lib/matplotlib/backend_bases.py
Line 1673 in b2e8434
So we need at least one more go-around to get this correct. I am going to see what it looks like to:
_original_dpiintoFiguretacaswell commentedon Dec 7, 2022
tagging as 3.7 as the amount of changes I am planning I expect to be bigger than what I would like to backport, but can be talked out of that (and probably should wait to see the code before jumping to conclusions anyway).
QuLogic commentedon Dec 8, 2022
Oh, I thought I saw the
set_dpiissue before, maybe I didn't fix it? I expect this would be fixed by my refactor of the HiDPI handling, but I've not touched that in some time.BearBearCodes commentedon Dec 9, 2022
Upon updating
matplotlib-inlinefromv0.1.3tov0.1.6, I can confirm that changing thefigure.dpioption inmatplotlibrcworks now. Also, the default dpi in a Jupyter notebook is now 100, which is the correct behaviour (previously it was 72 dpi inside a Jupyter notebook withmatplotlib-inline 0.1.3).Unfortunately,
fig.set_dpi(150)still does not change the dpi of the saved figure, so the saved figure is still at 100 dpi.Here is the output of the code snippet in my original issue after updating to

matplotlib-inline 0.1.6(with nomatplotlibrcfile):tacaswell commentedon Dec 9, 2022
As an update, I took at pass at this and failed. @QuLogic has a plan to fix this at a lower level.
jklymak commentedon Dec 9, 2022
Just to clarify this a bit, because I think its being muddied by hiDPI and inline issues:
dpi set on creation:
Boo.pnghas 150 dpidpi set after creation:
Boo.pnghas the dpi of 100.No doubt because
matplotlib/lib/matplotlib/backend_bases.py
Line 2301 in a5f5af3
fig._original_dpi.jklymak commentedon Dec 9, 2022
Note that if we just modify
set_dpito change_original_dpithat fixes the problem here.It doesn't fix the original issue #11227, which is somewhat orthogonal.
jklymak commentedon Dec 9, 2022
So far as I can tell,
set_dpiis completely untested. I'd actually propose deprecating it, as there is not much reason to call it.tacaswell commentedon Aug 11, 2023
Figure.set_dpiworks correctly if you have a figure open interactively, this is a bug we should fix.