Skip to content

fix for issue #5201, empty extension triangle for vmin < 1.0 #5319

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
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/matplotlib/colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,9 +674,9 @@ def _process_values(self, b=None):

b = self.norm.inverse(self._uniform_y(self.cmap.N + 1))
if self._extend_lower():
b[0] = b[0] - 1
b[0] = 0.9 * b[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 haven't completely thought this through, but it looks to me like using a multiplier is fine for the specific case where the problem arose--a log norm--but not for the case of a linear norm. If b[0] or b[1] is zero, the multiplier doesn't do anything at all.
It also looks like the extend logic here might not even be needed, given the extend logic in _uniform_y(). I haven't checked to see how much of that was added when the ends were modified to be of variable length.
The point of all this is just to find extended b values that will be normed to less than 0 if "under" or more than 1 if "over".

Copy link
Member

Choose a reason for hiding this comment

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

Maybe the nicest way to handle this would be to have the norm itself define two special values, one such that its norm is less than zero, and the other such that its norm is greater than one. Then the colorbar code here could just plug in those values as needed.

Copy link
Author

Choose a reason for hiding this comment

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

It seems changing the end values is not needed for LogNorm the plot will look fine without the multiplier. The only 2 other Norm objects that reach this code are: SymLogNorm and PowerNorm. SymLogNorm cannot be inverted, so it won't work in a colorbar like this. PowerNorm has a different problem at the lower end point, I'll look into it some more...

if self._extend_upper():
b[-1] = b[-1] + 1
b[-1] = 1.1 * b[-1]
self._process_values(b)

def _find_range(self):
Expand Down
13 changes: 12 additions & 1 deletion lib/matplotlib/tests/test_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import matplotlib.pyplot as plt
from matplotlib import rcParams
from matplotlib.colors import BoundaryNorm
from matplotlib.colors import LogNorm
from matplotlib.cm import get_cmap
from matplotlib import cm
from matplotlib.colorbar import ColorbarBase
from nose.tools import assert_greater_equal


def _get_cmap_norms():
Expand Down Expand Up @@ -254,7 +256,16 @@ def test_colorbarbase():
ax = plt.gca()
ColorbarBase(ax, plt.cm.bone)


@cleanup
def test_colorbar_lognorm_extension():
# Issue #5201: empty triangle plotted
# for logarithmic colorbar with vmin < 1.0
ax = plt.gca()

cb = ColorbarBase(ax, norm=LogNorm(vmin=1, vmax=1000.0), orientation='vertical', extend='both')

assert_greater_equal(cb._values[0], 0.0)

@image_comparison(
baseline_images=['colorbar_closed_patch'],
remove_text=True)
Expand Down