I'm not sure whether this is really a bug or I'm just using an inconsistent combination of options. Under some specific circumstances (see below) compressed layout is not applied the second time a figure is saved.
If I do not set the rcParams, all is well. If I do not set bbox_inches="tight" in my calls to savefig, the images are identical (but I have too much white space top and bottom). Maybe there is a better option than bbox_inches="tight" when using compressed layout?
For context, my real example is a script that makes several figures. For most of them I want constrained layout, so I set that once in the rcParams for convenience. Only one figure needs "compressed", and I am saving twice because I want both a png and a pdf. Fixed it in my current example by just reverting the rcParams setting for the one figure.
Yeah we do some dancing around when we save with bbox inches - so this seems to get caught in that. I tried to track it down, but the figure-saving stack is full of context managers, and I can't see where the layout manager gets reset. Hopefully someone more cognizant of that part of the codebase can explain.
It is, but I don't understand what _cm_set does to reset the layout engine after this. Somehow it is dropping the old layout engine and making a new one, and the new one doesn't know that the old one was a 'compressed' engine.
It calls get_{kwarg} and after running calls set({kwarg}={old value}). So here it calls oldvalue = figure.get_layout_engine() and figure.set(layout_engine=oldvalue). Is figure.set_layout_engine(figure.get_layout_engine()) working correctly?
Activity
jklymak commented on Jan 12, 2023
Yeah we do some dancing around when we save with bbox inches - so this seems to get caught in that. I tried to track it down, but the figure-saving stack is full of context managers, and I can't see where the layout manager gets reset. Hopefully someone more cognizant of that part of the codebase can explain.
rcomer commented on Jan 12, 2023
Thanks for looking @jklymak 🙂
QuLogic commented on Jan 13, 2023
I think it is set (temporarily) here;
matplotlib/lib/matplotlib/backend_bases.py
Lines 2356 to 2357 in 018c5ef
jklymak commented on Jan 13, 2023
It is, but I don't understand what _cm_set does to reset the layout engine after this. Somehow it is dropping the old layout engine and making a new one, and the new one doesn't know that the old one was a 'compressed' engine.
QuLogic commented on Jan 13, 2023
It calls get_{kwarg} and after running calls set({kwarg}={old value}). So here it calls oldvalue = figure.get_layout_engine() and figure.set(layout_engine=oldvalue). Is figure.set_layout_engine(figure.get_layout_engine()) working correctly?
rcomer commented on Jan 13, 2023
I am way out of my depth here but
Without the rcParams line, fig.get_layout_engine() returns None after the savefig.
rcomer commented on Jan 13, 2023
I think the problem is the call to adjust_bbox
matplotlib/lib/matplotlib/backend_bases.py
Lines 2349 to 2350 in 018c5ef
which explicity calls
matplotlib/lib/matplotlib/_tight_bbox.py
Line 21 in a3011df
which will use the default constrained layout engine if the rcParams is set
matplotlib/lib/matplotlib/figure.py
Lines 2599 to 2610 in a3011df