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

FIX: minor log ticks overwrite#13126

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
anntzer merged 4 commits intomatplotlib:masterfromjklymak:fix-minor-log
Jan 11, 2019
Merged

Conversation

jklymak
Copy link
Member

@jklymakjklymak commentedJan 7, 2019
edited
Loading

PR Summary

  • needs tests...

attempting to fix log overprint issue (closes#13112)

importmatplotlib.pyplotaspltfig,axs=plt.subplots(3,3,figsize=(8,8),constrained_layout=True)axs[0,0].semilogy([10000,2500], [10000,10010])axs[0,1].semilogy([10000,2500], [10000,10100])axs[0,2].semilogy([10000,2500], [10000,11000])axs[1,0].semilogy([10000,2500], [10000,25000])axs[1,1].semilogy([10000,2500], [10000,55000])axs[1,2].semilogy([10000,2500], [10000,85000])axs[2,0].semilogy([10000,2500], [10000,100000])axs[2,1].semilogy([10000,2500], [10000,120000])axs[2,2].semilogy([10000,2500], [10000,850000])#ax.set_yticks([10000, 20000, 25000])plt.show()

Before:

baras

After

booooo

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

@anntzer
Copy link
Contributor

I think the change onticker.py's side should look something like

diff --git i/lib/matplotlib/ticker.py w/lib/matplotlib/ticker.pyindex 89e077a04..84bd9a2b4 100644--- i/lib/matplotlib/ticker.py+++ w/lib/matplotlib/ticker.py@@ -2093,9 +2093,7 @@ def is_decade(x, base=10):   def is_close_to_int(x):-    if not np.isfinite(x):-        return False-    return abs(x - round(x)) < 1e-10+    return abs(x - np.round(x)) < 1e-10   class LogLocator(Locator):@@ -2256,7 +2254,11 @@ class LogLocator(Locator):             # If we're a minor locator *that expects at least two ticks per             # decade* and the major locator stride is 1 and there's no more             # than one minor tick, switch to AutoLocator.-            return AutoLocator().tick_values(vmin, vmax)+            ticklocs = AutoLocator().tick_values(vmin, vmax)+            # Don't overstrike the major labels.+            ticklocs = ticklocs[+                ~is_close_to_int(np.log(ticklocs) / np.log(b))]+            return ticklocs         return self.raise_if_exceeds(ticklocs)      def view_limits(self, vmin, vmax):

after which I don't know if the other changes (touching labelOnlyBase) are needed?

@jklymak
Copy link
MemberAuthor

Yeah that might be better.

Not sure we should be implying that a locator is a minor locator. My preference would be that we just explicitly pass the major locator instance to anything we want to be a minor locator and then do a set diff between the two locators Or simply doing this in the axis code after the fact where we know about both locators.

@anntzer
Copy link
Contributor

The log locator code already has "magic" to guess whether it's a minor or a major locator; given that it's already assuming that it works we may as well rely on it.
As argued in a bunch of other places it is indeed suboptimal that tickers don't really know whether they are major or minor, but adding more logic to clean that up on the axis side seems worse.

@jklymak
Copy link
MemberAuthor

I'd argue that the "magic" is probably a bad idea because it relies on the user knowing the magic when they specify the Locator, and as we have seen, even the developers don't get the "magic" right.

I think there are two approaches - 1) tell the locator explicitly what ticks to avoid with an optionalmajor_ticks=None kwarg, or 2) get the ticks from both locators, and then exclude any overlaps in the minor ticks.

I guess I think 1) is the best because I can think of cases where the minorLocator might want to exclude a tick because it isclose but not equal to a major tick. I don't see why we can't impliment this as aLocator._remove_duplicates method that defaults on all Locators to removing all the duplicates in the__call__. If child classes want to ignore all this they can, so I don't think it'd be a backwards incompatibility issue.

@jklymak
Copy link
MemberAuthor

(BTW implimenting your change to squash the bug, the other discussion is more long-term)

return AutoLocator().tick_values(vmin, vmax)
ticklocs = AutoLocator().tick_values(vmin, vmax)
# Don't overstrike the major labels.
ticklocs = [t for t in ticklocs if
Copy link
Contributor

Choose a reason for hiding this comment

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

eh, that needs to use boolean indexing, no?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Not sure what you mean? Your version didn't work because ticklocs is an array andis_close_to_int only works on a single value. Thisseems to work...

Copy link
Contributor

Choose a reason for hiding this comment

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

My patchalso fixed is_close_to_int to be vectorized: it deleted the lines

-    if not np.isfinite(x):-        return False

you may have missed that?
(ifx is not finite, the expression below will also be false).

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Ah, my fault.

@timhoffm
Copy link
Member

I think there are two approaches - 1) tell the locator explicitly what ticks to avoid with an optional major_ticks=None kwarg, or 2) get the ticks from both locators, and then exclude any overlaps in the minor ticks.

I would name thisexclude_ticks=None, which is more general. It may take a list of values and/or (possibly also later implemented) a locator.

jklymak reacted with thumbs up emoji

@jklymakjklymak changed the titleWIP/FIX: minor log ticks overwriteFIX: minor log ticks overwriteJan 7, 2019
@jklymakjklymakforce-pushed thefix-minor-log branch 2 times, most recently from6e15b71 to5c9d3bdCompareJanuary 9, 2019 18:57
@jklymakjklymak added this to thev3.0.3 milestoneJan 9, 2019
# Don't overstrike the major labels.
ticklocs = ticklocs[
~is_close_to_int(np.log(ticklocs) / np.log(b))]
print('ticklocs', ticklocs)
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this line

@@ -2250,13 +2248,19 @@ def tick_values(self, vmin, vmax):
ticklocs = b ** decades

_log.debug('ticklocs %r', ticklocs)
print('subs', subs, have_subs, ticklocs)
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this line

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Oooops, sorry

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.

I guess that can count as Jody's approval of my patch :)

ticklocs = AutoLocator().tick_values(vmin, vmax)
# Don't overstrike the major labels.
ticklocs = ticklocs[
~is_close_to_int(np.log(ticklocs) / np.log(b))]
Copy link
Member

Choose a reason for hiding this comment

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

This looks like a hard-coded assumption on the position of the major ticks. Will this fail if I’ve set non-default values no the major locator?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Absolutely. See discussion above for fixing that. But that assumption is already in the code, this just makes that assumption work properly under all conditions. The next step is to get rid of the assumption, but thats a bigger project.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, that's reasonable for now. However, it would be good to explicitly document this in the code with a comment (unless you're immediately following up with the full fix).

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Sure thing

Copy link
Member

@timhoffmtimhoffm left a comment

Choose a reason for hiding this comment

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

Anybody can merge after CI pass.

@anntzeranntzer merged commit71dd3ae intomatplotlib:masterJan 11, 2019
@lumberbot-app
Copy link

Owee, I'm MrMeeseeks, Look at me.

There seem to be a conflict, please backport manually. Here are approximate instructions:

  1. Checkout backport branch and update it.
$ git checkout v3.0.x$ git pull
  1. Cherry pick the first parent branch of the this PR on top of the older branch:
$ git cherry-pick -m1 71dd3ae125d060bc08193abb93cca643245e3de0
  1. You will likely have some merge/cherry-pick conflict here, fix them and commit:
$ git commit -am 'Backport PR #13126: FIX: minor log ticks overwrite'
  1. Push to a named branch :
git push YOURFORK v3.0.x:auto-backport-of-pr-13126-on-v3.0.x
  1. Create a PR against branch v3.0.x, I would have named this PR:

"Backport PR#13126 on branch v3.0.x"

And apply the correct labels and milestones.

Congratulation you did some good work ! Hopefully your backport PR will be tested by the continuous integration and merged soon!

If these instruction are inaccurate, feel free tosuggest an improvement.

@timhoffm
Copy link
Member

Automatic backport fails due to#12865 not being backported. We should either backport both or none.

@tacaswelltacaswell modified the milestones:v3.0.3,v3.1Jan 12, 2019
@tacaswell
Copy link
Member

Moved both to 3.1. The logic around the log ticks is subtle and probably better to keep changes to it for minor release (not patch releases).

jklymak reacted with thumbs up emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@anntzeranntzeranntzer approved these changes

@timhoffmtimhoffmtimhoffm approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v3.1.0
Development

Successfully merging this pull request may close these issues.

LogNorm colorbar prints double tick labels after set_ticks()
5 participants
@jklymak@anntzer@timhoffm@tacaswell@QuLogic

[8]ページ先頭

©2009-2025 Movatter.jp