Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

BUG: Prevent Tick params calls from overwriting visibility without being told to#12839

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
dopplershift merged 6 commits intomatplotlib:masterfromksunden:tick_params
Feb 25, 2019

Conversation

ksunden
Copy link
Member

PR Summary

Prevents a regression bisected to#10088, which caused subsequent calls totick_params to overwrite the visibility of tick labels (et al.) when those calls did not set visibility themselves.

Just pops a subset of the kwargs out of the dictionary and replaces them after the call to_apply_params is made, so that they are there for other parts of the codebase (including tests).

The test included here passes on current release (v3.0.2), but fails on current master (
936855c).

PR Checklist

  • Has Pytest style unit tests
  • Code isFlake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

for d in dicts:
if reset:
d.clear()
blacklist_dicts.append(
{k: d.pop(k) for k in blacklist if k in d.keys()}
Copy link

@42B42BNov 19, 2018
edited
Loading

Choose a reason for hiding this comment

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

First, either this line seems to be indented too far or the line above isn't indented enough? Second, I'm curious about if there is a better way to write this without using.pop and iterating throughd.keys() for every single lookup?

Copy link
MemberAuthor

@ksundenksundenNov 19, 2018
edited
Loading

Choose a reason for hiding this comment

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

I'll note that the iteration is only over the keys in the blacklist (total of 5 items),k in d.keys() is an O(1) check since keys view objects are set-like and hashable.

The second iteration could actually be rolled into this conditional, to prevent things from being popped then added back with updates, rather than popping indiscriminately and then iterating over the kwtrans keys.

fig, ax = plt.subplots()
plt.plot([0, 1, 2], [0, -1, 4])
plt.setp(ax.get_yticklabels(), visible=False)
ax.tick_params(axis="y", which="both", length=0)
Copy link
Member

Choose a reason for hiding this comment

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

I think this test could be easily done without an image comparison by just checking the visibility of the ticks?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

The tricky bit is that one of the common ways in tests of checking wheter the ticks are visible was lying to you prior to this PR, (though if you went to the individual ticks, it would be correct) As such, I was looking to make sure it translated to the image generated.

tacaswell reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

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

You can instead save to svg and use some long-ish strings as labels, and check that the labels don't appear as substrings in the svg file.

for d in dicts:
if reset:
d.clear()
blacklist_dicts.append(
Copy link
Member

Choose a reason for hiding this comment

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

I find this pretty opaque, and don’t really understand why these kwargs are different than the other kwargs (other than that they control visibility). This could really use a comment explaining what it does and why. As it stands, I’m not clear at all that this is the proper solution, and maybe there is something more fundamental that is at fault.

@anntzer
Copy link
Contributor

So the bug comes from the fact that plt.setp(... visible=False) set the visibility by calling tick.set_visible(False), which used to override tick_params() which would set reset label1On to True; but after#10088 label1On maps to set_visible and thus the call to tick_params undoes the call to set_visible(False).

I think a correct fix would be somewhere along the lines of

diff --git i/lib/matplotlib/axis.py w/lib/matplotlib/axis.pyindex 127c9c5b0..094cd53fd 100644--- i/lib/matplotlib/axis.py+++ w/lib/matplotlib/axis.py@@ -856,26 +856,16 @@ class Axis(martist.Artist):         For documentation of keyword arguments, see         :meth:`matplotlib.axes.Axes.tick_params`.         """-        dicts = []-        if which == 'major' or which == 'both':-            dicts.append(self._major_tick_kw)-        if which == 'minor' or which == 'both':-            dicts.append(self._minor_tick_kw)         kwtrans = self._translate_tick_kw(kw)-        for d in dicts:-            if reset:-                d.clear()-            d.update(kwtrans)-         if reset:             self.reset_ticks()         else:             if which == 'major' or which == 'both':                 for tick in self.majorTicks:-                    tick._apply_params(**self._major_tick_kw)+                    tick._apply_params(**kwtrans)             if which == 'minor' or which == 'both':                 for tick in self.minorTicks:-                    tick._apply_params(**self._minor_tick_kw)+                    tick._apply_params(**kwtrans)             if 'labelcolor' in kwtrans:                 self.offsetText.set_color(kwtrans['labelcolor'])         self.stale = True

plus some wrangling with the rest of the codebase to keep track of label1On-ness.

Release critical as a regression.

@anntzeranntzer added this to thev3.1.0 milestoneFeb 7, 2019
@anntzeranntzer added the Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. labelFeb 7, 2019
@ksunden
Copy link
MemberAuthor

If I recall correctly, I had tried something like the simpler diff you presented here, but got several new test failures as a result. It may very well be easy to track those down in a cleaner way, though my inital efforts focused on fixing the problem fairily locally.

@anntzer
Copy link
Contributor

I think a simpler approach may be possible but this looks generally ok as a stopgap if nothing better is proposed before 3.1.

blacklist_dicts.append(
{
k: d.pop(k) for k in blacklist
if k in d.keys() and k not in kwtrans.keys()
Copy link
Contributor

Choose a reason for hiding this comment

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

k in d

Copy link
Contributor

@anntzeranntzer left a comment

Choose a reason for hiding this comment

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

Strongly suggest not adding a baseline image perhttps://github.com/matplotlib/matplotlib/pull/12839/files#r255441630.

@tacaswell
Copy link
Member

I am concerned about this fix. The underlying issue here is that the tick system has an internal set of defaults that it uses to create new ticks, but by usingplt.setp you are reaching in to change the state of the ticks without propagating that back the default dictionary. This skip-list works for visibility, but will not work for color (or any other property).
Doing

ax.tick_params(axis="y",which="both",label1On=False)ax.tick_params(axis="y",which="both",length=0)

works as expected.

I am 👎 on merging this. The correct fix is to track on the tick objects what state has been touch independently by the user and then not update that property.

I am also concerned that this will not work in the case where we generate more tick objects later so you will end up with mixed state.

tacaswell
tacaswell previously requested changesFeb 18, 2019
Copy link
Member

@tacaswelltacaswell left a comment

Choose a reason for hiding this comment

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

I do not think this is the correct fix to the problem (which is that we do not track if users have mutated objects that the axis thinks it is managing).

@tacaswell
Copy link
Member

It might be possible to use theget methods to check what state does not match the (previous) defaults and then skip applying based on that?

@ksunden
Copy link
MemberAuthor

To be clear, this is just taking out arguments only in the case that they were not asked for explicitly and simply not trying to change it. If the user is modifying the state using this function, those changesare propegated.

That said, I make no illusions, this is a hack, and there are certainly cleaner solutions, including changing my own library code such that thelabelOn, etc. get set to match.

The point about mixed state is a good one, however, if users intentionally got a mixed state (I would tend to avoid this myself, but still) The code without this patch will override that mixed state, even when the arguments that are written have nothing to do with visibility.

The way this is implemented preserves mixed state if it exists, but makes it easy to get back to a consistent state.

@tacaswelltacaswell removed the Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. labelFeb 23, 2019
@tacaswelltacaswell modified the milestones:v3.1.0,v3.2.0Feb 23, 2019
@tacaswelltacaswell added the Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. labelFeb 23, 2019
@tacaswelltacaswell modified the milestones:v3.2.0,v3.1.0Feb 23, 2019
@tacaswell
Copy link
Member

Sorry, being thrashy about milestones / tags... Still thinking about this.

@tacaswelltacaswell dismissed theirstale reviewFebruary 23, 2019 17:55

I have now pushed a commit to this branch.

@tacaswell
Copy link
Member

I applied half of the diff suggested in the comments by@anntzer (we still want to update the default settings fornew ticks) but only apply the passed-in kwargs to the existing ticks.

If I recall correctly, I had tried something like the simpler diff you presented here, but got several new test failures as a resul

@ksunden what tests failed for you locally with this change?


Went back and forth a bit on trying to understand what the intent of this method is (as it could be argued that the correct behavioris to re-apply the standard style to all of the ticks), but the presence of thereset kwargs suggests otherwise.

@ksunden
Copy link
MemberAuthor

I am not getting any local test failures now, I recall trying this back in november, but don't recall why I ultimately moved on from it. All looks good on my end now.

anntzer
anntzer previously requested changesFeb 24, 2019
Copy link
Contributor

@anntzeranntzer left a comment

Choose a reason for hiding this comment

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

Please try to not include a baseline image perhttps://github.com/matplotlib/matplotlib/pull/12839/files#r255441630. (I'm not 100% sure this will work, but is at least worth a try.)

@tacaswelltacaswell dismissedanntzer’sstale reviewFebruary 25, 2019 20:09

Saving 15Kb on a file is not worth the complexity of checking the text of an svg (discussed on phone call)

Copy link
Contributor

@dopplershiftdopplershift left a comment

Choose a reason for hiding this comment

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

I'm ok with adding another baseline image. It's only 15kb, and the alternative would actually be something out of line from the rest of the test suite and require more effort to understand what's going on.

@dopplershiftdopplershift merged commiteb92f62 intomatplotlib:masterFeb 25, 2019
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this pull requestFeb 25, 2019
@lumberbot-app
Copy link

Something went wrong ... Please have a look at my logs.

jklymak added a commit that referenced this pull requestFeb 25, 2019
…839-on-v3.1.xBackport PR#12839 on branch v3.1.x (BUG: Prevent Tick params calls from overwriting visibility without being told to)
@ksundenksunden deleted the tick_params branchFebruary 26, 2019 00:05
@ksundenksunden restored the tick_params branchMarch 29, 2019 16:22
has2k1 added a commit to has2k1/plotnine that referenced this pull requestJul 8, 2019
Aftermatplotlib/matplotlib#12839axis ticks showed up along all the edges of the plot paneland theming of tick labels was finicky.The solution is we have to be careful in how we toggle thevisibility of these elements. If not careful, merely settingthe tick/tick labels could switch on the visibility. Thiscould interfere with theme.closes#278
@ksundenksunden deleted the tick_params branchDecember 27, 2022 18:50
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@jklymakjklymakjklymak left review comments

@42B42B42B left review comments

@tacaswelltacaswelltacaswell approved these changes

@dopplershiftdopplershiftdopplershift approved these changes

@anntzeranntzeranntzer left review comments

Assignees
No one assigned
Labels
Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Projects
None yet
Milestone
v3.1.0
Development

Successfully merging this pull request may close these issues.

6 participants
@ksunden@anntzer@tacaswell@dopplershift@jklymak@42B

[8]ページ先頭

©2009-2025 Movatter.jp