-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Specify custom tick space heuristic in MaxNLocator #11027
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm 50/50 on the utility of this, and dubious about adding another kwarg given that the new kwarg is only used if the nbins = 'auto'.
I think this is a pretty obscure use case, but if you think its important, it will only get used if there is an example somewhere...
@@ -1821,6 +1822,12 @@ def __init__(self, *args, **kwargs): | |||
Relax `nbins` and `integer` constraints if necessary to | |||
obtain this minimum number of ticks. | |||
|
|||
*tick_space_heuristic* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest that this just be another option for nbins. i.e. if nbins is callable it is used to determine the heuristic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great idea!
@@ -1882,11 +1889,17 @@ def set_params(self, **kwargs): | |||
self._extended_steps = self._staircase(self._steps) | |||
if 'integer' in kwargs: | |||
self._integer = kwargs['integer'] | |||
if 'tick_space_heuristic' in kwargs: | |||
tick_space_heuristic = kwargs['tick_space_heuristic'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we just use kwarg.pop
these days...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine by me. I was just following the style used in the rest of the set_params
function. Do you think I should convert the entire function then? Seems like something for a different PR, but I don't mind doing it here.
@@ -1760,6 +1760,11 @@ def get_minpos(self): | |||
raise NotImplementedError() | |||
|
|||
|
|||
def tick_space_heuristic(axis_length, label_fontsize, label_fontsize_factor): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be private I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean prepend the function with an underscore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
I am 👎 on this going in as-is. My primary concern is expanding the public API of the Axis classes to serve the needs of one of the Locator classes. Even if I were convinced that adding an extra coupling between the locator and the ticker was the right thing to do, I am not sure that this is the right path. It might be better to ex add a method to the Axis that returns both the length of the axis, the font-size, and the orientation of the font relative to the axis (parallel, particularize, or rotated). If I were convinced that this is a good idea and this is the right API to add, it will need to be much better documented and motivated. I think a better course path here would be to make it easier to set the default XAxis, YAxis, and tick-related classes used by Matplotlib (it looks like you can currently do it by over-riding a private method on Axes to use your prefered classes and then re-registering your new class Axes class with the projection framework, yikes!). attn @timhoffm for more ticker-related issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment for details, concerned about expanding the public API in this way.
@tacaswell. The horse is already out of the barn on that one; axis.get_tick_spacing predates this PR and is explicitly used for MaxNLpcator as far as I can tell |
Following #11025 (comment), I can make an example using AxesGrid that shows the problem I have with the ticks and compares to a plot using the custom tick heuristic to make it look nicer. |
@tacaswell: regarding extending public API, what if I follow @jklymak's suggestion of using the As @jklymak said, the coupling between The problem I see with setting different defaults (which I agree would be nicer) is that there is currently no option among the existing Locators to do something that acts like |
We discussed this on the weekly phone call and came to the following suggestion:
Notes are at https://paper.dropbox.com/doc/Matplotlib-meeting-agenda-aAmENlkgepgsMeDZtlsYu |
ping @egpbos are you still interested in keeping this alive given the feedback above? |
@jklymak I'm interested, but currently I have some other priorities, so won't get to it any time soon. |
OK, I'm going to close this as not having enough support. Maybe something like this can go in an example showing how to subclass MaxNLocator? |
PR Summary
Following discussion in #11025, I added an optional argument to MaxNLocator (and hence AutoLocator) to specify a custom heuristic for spacing ticks. It allows people to experiment with their own spacing rules without having to change Matplotlib source code. This way, one can benefit from the automatic spacing introduced in Matplotlib 2 (if I understand correctly), but still customize it if deemed necessary (which was the case for me as discussed in #11025).
PR Checklist
Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way