Skip to content

[Bug]: rcdefaults and rcParams.clear() don't work?  #25855

Closed as not planned
Closed as not planned

Description

@chahak13

Bug summary

This is the rcdefaults() function

def rcdefaults():
"""
Restore the `.rcParams` from Matplotlib's internal default style.
Style-blacklisted `.rcParams` (defined in
``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
See Also
--------
matplotlib.rc_file_defaults
Restore the `.rcParams` from the rc file originally loaded by
Matplotlib.
matplotlib.style.use
Use a specific style file. Call ``style.use('default')`` to restore
the default style.
"""
# Deprecation warnings were already handled when creating rcParamsDefault,
# no need to reemit them here.
with _api.suppress_matplotlib_deprecation_warning():
from .style.core import STYLE_BLACKLIST
rcParams.clear()
rcParams.update({k: v for k, v in rcParamsDefault.items()
if k not in STYLE_BLACKLIST})

What exactly are we trying to do here? According to the docstring, if we're trying to reset the rcParams dictionary and only reset the keys that are not in STYLE_BLACKLIST then there are 2 problems I think:

  1. rcParams.clear() doesn't work. It doesn't clear out the entire dictionary.
  2. After the update line, rcParams will still have keys from STYLE_BLACKLIST which, if I were to perform the same operations on a dictionary, shouldn't be the case.
  3. While it does make sense to still have the keys from STYLE_BLACKLIST but then I'm not sure why clear() is used and not just directly update the keys.

Also, sidenote, popitem() errors out without a good error message (which is also why clear doesn't actually empty the dict?)

Code for reproduction

In [3]: mpl.rcParams["webagg.port"]
Out[3]: 8988

In [4]: mpl.rcParams["webagg.port"] = 9000

In [5]: mpl.rcParams["webagg.port"]
Out[5]: 9000

In [6]: mpl.rcdefaults()

In [7]: mpl.rcParams["webagg.port"]
Out[7]: 9000

In [8]: mpl.rcParams.clear()

In [9]: mpl.rcParams["webagg.port"]
Out[9]: 9000

Actual outcome

clear() doesn't empty the rcParams dictionary.

Expected outcome

clear() should empty the dictionary and after rcdefaults(), keys from STYLE_BLACKLIST shouldn't be there.

Additional information

I'm not sure if this is a documentation issue and the behaviour is intended or the behaviour isn't intended.

Operating system

No response

Matplotlib Version

Current main

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Activity

  1. chahak13 commented on May 11, 2023

    @chahak13
    ContributorAuthor

    Seems like @timhoffm came across this while doing something similar in #12577 (comment)

    The defaults should have also STYLE_BLACKLIST parameters.

    The logic (iirc) was that anything that was not style should not be changed by the restore-default methods.

    Based on @tacaswell's comment on that, it still doesn't make sense because right now they are persisted even though the code seems to be removing them?

    I'm kinda confused about what exactly is the goal here.

  2. changed the title [-][Bug]: `rcdefaults` doesn't work? [/-] [+][Bug]: `rcdefaults` and `rcParams.clear()` don't work? [/+] on May 11, 2023
  3. ksunden commented on May 11, 2023

    @ksunden
    Member

    webagg.port is specifically in the STYLE_BLACKLIST which is explicitly excluded by the documentation for rcdefaults

    The dict inheritance makes it confusing, as we don't actually directly implement __delitem__ but I am surprised that clear doesn't clear out everything.

    If I call dict.clear(mpl.rcParams) it does clear out everything...

    Somehow we are getting delitem and clear from MutableMapping and not actually properly inheriting from dict as was likely intended.

  4. ksunden commented on May 11, 2023

    @ksunden
    Member

    For completeness, here is the STYLE_BLACKLIST:

    {
        'webagg.port_retries',
        'figure.raise_window',
        'docstring.hardcopy',
        'backend',
        'backend_fallback',
        'toolbar',
        'figure.max_open_warning',
        'date.epoch',
        'timezone',
        'webagg.port',
        'webagg.open_in_browser',
        'webagg.address',
        'interactive',
        'tk.window_focus',
        'savefig.directory'
    }
  5. chahak13 commented on May 11, 2023

    @chahak13
    ContributorAuthor

    Yep. I get that the STYLE_BLACKLIST is excluded but if clear() works as it normally would, then that means that webagg.port and any other entry in STYLE_BLACKLIST should not be in there.

  6. chahak13 commented on May 11, 2023

    @chahak13
    ContributorAuthor

    I think the reason it gets the MutableMapping is because our inheritance is defined as MutableMapping first and then dict.

  7. chahak13 commented on May 11, 2023

    @chahak13
    ContributorAuthor

    Basically, it feels like the "wrong" implementation is working right now?

  8. ksunden commented on May 11, 2023

    @ksunden
    Member

    In general inheriting from dict was a mistake (and that is what #25617 is addressing)

    If I do del mpl.rcParams["backend"] I get KeyError (despite the key actually being there)

    Yeah, I think that rcdefaults is a no-op currently, which is not intended...

    We do not test it at all.

    Given that it broke and nobody complained... perhaps that is a sign it should be either deprecated completely or reworked entirely as part of #25617... It perhaps gives some latitude to make changes that might otherwise have warranted a difficult to navigate deprecation dance.

    With the chainmap implementation (modulo the sub-dict structures) the documented behavior appears to be something like:

    non_style = {k: self[k] for k in STYLE_BLACKLIST}
    self.maps = [defaults, non_style]
    self.maps.new_child()

    (this is from the perspective of self being a ChainMap and defaults being available, but more or less that is I think what the documented behavior is)

    And of course, should get a test...

  9. chahak13 commented on May 11, 2023

    @chahak13
    ContributorAuthor

    Yeah, I think I'll redo the implementation there to match the documentation more.

  10. github-actions commented on Jun 22, 2026

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  11. added
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions