Skip to content
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

Add _val_or_rc-function #26168

Merged
merged 1 commit into from Jul 28, 2023
Merged

Add _val_or_rc-function #26168

merged 1 commit into from Jul 28, 2023

Conversation

oscargus
Copy link
Contributor

@oscargus oscargus commented Jun 22, 2023

PR summary

if foo is None:
    foo = mpl.rcParams["bar.foo"]

is a very common code pattern, so may be good to have a helper for it. Right now I only considered legend.py, but if this is an accepted idea there are many places where it can be used.

(And, yes, the reason I started with legend is that it was defined as a local function there.)

PR checklist

@oscargus oscargus force-pushed the valorrc branch 6 times, most recently from 3cfb5fc to bc1658e Compare June 22, 2023 16:58
Copy link
Member

@efiring efiring left a comment

Choose a reason for hiding this comment

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

Because legend.val_or_rc is formally public API, it probably should be removed after a standard deprecation cycle.

@oscargus
Copy link
Contributor Author

I do not think that? I think it is an internal function in __init__ that is not accessible from the outside?

Copy link
Member

@efiring efiring left a comment

Choose a reason for hiding this comment

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

Oops! You are right, of course. All set.

@@ -603,11 +592,9 @@ def val_or_rc(val, rc_name):
'markeredgecolor': ['get_markeredgecolor', 'get_edgecolor'],
'mec': ['get_markeredgecolor', 'get_edgecolor'],
}
labelcolor = mpl._val_or_rc(labelcolor, 'legend.labelcolor')
Copy link
Contributor

Choose a reason for hiding this comment

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

You could nest another mpl._val_or_rc(..., 'text.color') here and add a short comment about falling back to text.color if legend.labelcolor is not present.

Comment on lines -450 to -451
def val_or_rc(val, rc_name):
return val if val is not None else mpl.rcParams[rc_name]
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 could possibly save a bunch of method gets below by setting this and reusing it?
val_or_rc = mpl._val_or_rc

Copy link
Member

Choose a reason for hiding this comment

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

I would like to warn on ineffective micro optimizations. Squeezing out nanoseconds does not make any measureable difference.

A function lookup cost 30ns (Python 3.11):

In [2]: %timeit mpl.rc_params_from_file
29.7 ns ± 0.544 ns per loop

If we want to improve performance (and there's a lot to gain) that would need to be guided by profiling to identify the real pain points. In other cases, code structure/readability should be the primary guideline. - Not shure what is better here, but I tend to not do the additional logic indirection for saving a method to a new variable just to save method lookups.

@@ -1294,6 +1294,13 @@ def is_interactive():
return rcParams['interactive']


def _val_or_rc(val, rc_name):
"""
If *val* is None, return ``mpl.rcParams[rc_name]``, otherwise return val.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
If *val* is None, return ``mpl.rcParams[rc_name]``, otherwise return val.
Return the value if present, otherwise lookup `rc_name` in the rcParams dictionary.

I'd suggest rewording this to be more human friendly since the code already explains what you had written.

Copy link
Member

Choose a reason for hiding this comment

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

Using None and mpl.rcParams[rc_name] is good, because that's precise and comprehensible. Optional, slightly less algorithmic variant.

Suggested change
If *val* is None, return ``mpl.rcParams[rc_name]``, otherwise return val.
Pass *val* through unless it is None, in which case return ``mpl.rcParams[rc_name]``.

@@ -1294,6 +1294,13 @@ def is_interactive():
return rcParams['interactive']


def _val_or_rc(val, rc_name):
"""
If *val* is None, return ``mpl.rcParams[rc_name]``, otherwise return val.
Copy link
Member

Choose a reason for hiding this comment

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

Using None and mpl.rcParams[rc_name] is good, because that's precise and comprehensible. Optional, slightly less algorithmic variant.

Suggested change
If *val* is None, return ``mpl.rcParams[rc_name]``, otherwise return val.
Pass *val* through unless it is None, in which case return ``mpl.rcParams[rc_name]``.

@greglucas greglucas merged commit 72888a1 into matplotlib:main Jul 28, 2023
38 of 39 checks passed
@QuLogic QuLogic added this to the v3.8.0 milestone Jul 28, 2023
QuLogic added a commit to QuLogic/matplotlib that referenced this pull request Aug 15, 2023
I think an accident during confict resolution of matplotlib#26168 incorrectly
overwrote antialias settings for MathText.

Also, re-arrange the tests to better catch this error.
QuLogic added a commit to QuLogic/matplotlib that referenced this pull request Aug 15, 2023
I think an accident during confict resolution of matplotlib#26168 incorrectly
overwrote antialias settings for MathText. This puts the `_val_or_rc`
call in the correct location.

Also, re-arrange the tests to better catch this error.
@QuLogic QuLogic mentioned this pull request Aug 15, 2023
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants