Skip to content

extra minor-ticks on the colorbar when used with the extend option #11510

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

Closed
pharshalp opened this issue Jun 26, 2018 · 8 comments · Fixed by #11584
Closed

extra minor-ticks on the colorbar when used with the extend option #11510

pharshalp opened this issue Jun 26, 2018 · 8 comments · Fixed by #11584
Assignees
Milestone

Comments

@pharshalp
Copy link
Contributor

Bug report

Bug summary
extra minor-ticks show up on the colorbar when it is extended (at either or both ends).

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np

# Making yticks longer in length to highlight the issue
plt.rcParams['ytick.major.size'] = 10
plt.rcParams['ytick.minor.size'] = 4


np.random.seed(seed=12345)
x = np.random.randn(20, 20)
fig, ax = plt.subplots()
im = ax.pcolormesh(x)

cbar = fig.colorbar(im, extend='both')
cbar.ax.minorticks_on()
plt.show()

Actual outcome
figure_1

Matplotlib version

  • Operating system: MacOSX
  • Matplotlib version: 2.2.2
  • Matplotlib backend (print(matplotlib.get_backend())): MacOSX
  • Python version: Python 3.6.5

Installed via anaconda (default channel)

@pharshalp pharshalp changed the title minor-ticks on the colorbar when used with the extend option extra minor-ticks on the colorbar when used with the extend option Jun 26, 2018
@pharshalp
Copy link
Contributor Author

I tried digging around in matplotlib/colorbar.py and found the following...

class _ColorbarAutoLocator(ticker.MaxNLocator):
    """
    AutoLocator for Colorbar
    This locator is just a `.MaxNLocator` except the min and max are
    clipped by the norm's min and max (i.e. vmin/vmax from the
    image/pcolor/contour object).  This is necessary so ticks don't
    extrude into the "extend regions".
    """

This seems to suggest that the major ticks are calculated taking into account the extend regions.

@TarasKuzyo
Copy link
Contributor

If you add vmax=5 to im = ax.pcolormesh(x), you'll get -3 extruded into the "extend regions".

plot

@jklymak jklymak self-assigned this Jul 2, 2018
@jklymak jklymak modified the milestones: v3.0, v3.1 Jul 2, 2018
@jklymak
Copy link
Member

jklymak commented Jul 2, 2018

Thanks for the report. Downgraded to 3.1 because this is a pretty old problem, usually obviated by not using minor ticks for colorbars.

What should happen is that colorbars get special treatment in choosing ticks. They got really special treatment before and that causes other problems.

I'll see what I can figure out, but it may take a bit. Of course if anyone else has a clever solution that would be great. The fundamental problem is that the colorbar extend triangles are drawn inside the colorbar axes, so the ticks try to extend off there. I suspect a solution where they draw outside the axes and aren't clipped to the axes is the best way to fix this.

@pharshalp
Copy link
Contributor Author

@jklymak Thanks.
@TarasKuzyo the problem with the major ticks seems to go away when you specify both vmin and vmax (e.g. vmin=-3, vmax=5)
figure_1

@jklymak jklymak mentioned this issue Jul 3, 2018
6 tasks
@jklymak
Copy link
Member

jklymak commented Jul 3, 2018

See #11556 for the major tick problem

For the minor tick problem, thats a bit harder because how you are calling it, the method has no way to know you are trying to set the tick locator for a colorbar axes. I'd suggest we add a new method to the colorbar object (not its axes) that turns the minor ticks on for the axes, i.e. cb.minorticks_on/off().

@pharshalp
Copy link
Contributor Author

@jklymak Thanks for your quick response and PR.

Taking a clue from you PR, can something like the following be used for cb.minorticks_on/off()?

def minorticks_on(self):
    if self.orientation == 'vertical':
        long_axis, short_axis = ax.yaxis, ax.xaxis
    else:
        long_axis, short_axis = ax.xaxis, ax.yaxis

    long_axis.set_minor_locator(_ColorbarAutoLocator(self))

def minorticks_off(self):
    if self.orientation == 'vertical':
        long_axis, short_axis = ax.yaxis, ax.xaxis
    else:
        long_axis, short_axis = ax.xaxis, ax.yaxis

    long_axis.set_minor_locator(ticker.NullLocator())

@jklymak
Copy link
Member

jklymak commented Jul 3, 2018

I think that might work (plus doc string, plus API add etc... ;-) but you may also have to make a new _ColorbarAutoMinorLocator. I'm not sure.

Of course it'll still have an error until #11556 goes in, but could be done in parallel. If you wanted to make a PR, I'm happy to help and review.

@pharshalp
Copy link
Contributor Author

Sure, I will give it a try in a day or two. Would certainly appreciate your help.

@QuLogic QuLogic modified the milestones: v3.1, v3.0 Jul 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants