Skip to content

FIX: savefig)...,transparent=True) now makes inset_axes transparent a… #22816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3061,10 +3061,24 @@ def savefig(self, fname, *, transparent=None, **kwargs):
if transparent:
kwargs.setdefault('facecolor', 'none')
kwargs.setdefault('edgecolor', 'none')
# set subfigure to appear transparent in printed image
for subfig in self.subfigs:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subfigures can be nested arbitrarily; this only handles one level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think another issue was supposed to be opened to handle this general case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nesting should be handled here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tacaswell noted how to do this recursively here #22816 (comment)
This could also be done with a stack approach:

subfigs = [*self.subfigs]
while subfigs:
    this_subfig = subfigs.pop(0)
    subfigs.extend(this_subfig.subfigs)
    # Do something with this_subfig

On a side note (and not for this PR), I wonder if we want some kind of self.iter_subfigures or similar that would do the above iteration with a callable.

stack.enter_context(
subfig.patch._cm_set(
facecolor='none', edgecolor='none'))
for subfig_ax in subfig.axes:
stack.enter_context(
subfig_ax.patch._cm_set(
facecolor='none', edgecolor='none'))
# set axes to be transparent
for ax in self.axes:
stack.enter_context(
ax.patch._cm_set(facecolor='none', edgecolor='none'))

# set inset axes to be transparent as well
for child_ax in ax.child_axes:
stack.enter_context(
child_ax.patch._cm_set(
facecolor='none', edgecolor='none'))
self.canvas.print_figure(fname, **kwargs)

def ginput(self, n=1, timeout=30, show_clicks=True,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,24 @@ def test_savefig_pixel_ratio(backend):
assert ratio1 == ratio2


@image_comparison(['transparent_background'],
extensions=['png'], savefig_kwarg={'transparent': True},
remove_text=True)
def test_savefig_transparent():
# create two transparent subfigures with corresponding transparent inset
# axes. the entire background of the image should be transparent.
fig = plt.gcf()
gs = fig.add_gridspec(3, 3)
fig.add_subfigure(gs[0, 0])
fig.add_subplot(gs[0, 0])
ax = plt.gca()
ax.inset_axes([.1, .2, .3, .4])
fig.add_subfigure(gs[0:2, 1])
fig.add_subplot(gs[0:2, 1])
ax2 = plt.gca()
ax2.inset_axes([.1, .2, .3, .4])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can add ax.spines[:].set_visible(False); ax.set(xticks=[], yticks=[]) to all axes instantiations, which effectively makes them invisible (and thus the entire savefig should be invisible). Then you can check_figures_equal with a fully empty plot.



def test_figure_repr():
fig = plt.figure(figsize=(10, 20), dpi=10)
assert repr(fig) == "<Figure size 100x200 with 0 Axes>"
Expand Down