Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f4b5618

Browse files
authored
Merge pull request #9223 from dstansby/hexbin-log
Set norm to log if bins=='log' in hexbin
2 parents c273783 + 265eb1c commit f4b5618

File tree

4 files changed

+27
-13
lines changed

4 files changed

+27
-13
lines changed

doc/api/api_changes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,12 @@ Deprecations
451451
`.Legend.draggable()` is drepecated in favor of `.Legend.set_draggable()`.
452452
``Legend.draggable`` may be reintroduced as a property in future releases.
453453

454+
Colorbar for log-scaled hexbin
455+
------------------------------
456+
457+
When using `hexbin` and plotting with a logarithmic color scale, the colorbar
458+
ticks are now correctly log scaled. Previously the tick values were linear
459+
scaled log(number of counts).
454460

455461
API Changes in 2.2.0
456462
====================

lib/matplotlib/axes/_axes.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4326,9 +4326,23 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
43264326
offset_position="data"
43274327
)
43284328

4329+
# Check for valid norm
4330+
if norm is not None and not isinstance(norm, mcolors.Normalize):
4331+
msg = "'norm' must be an instance of 'mcolors.Normalize'"
4332+
raise ValueError(msg)
4333+
4334+
# Set normalizer if bins is 'log'
4335+
if bins == 'log':
4336+
if norm is not None:
4337+
warnings.warn("Only one of 'bins' and 'norm' arguments can be "
4338+
"supplied, ignoring bins={}".format(bins))
4339+
else:
4340+
norm = mcolors.LogNorm()
4341+
bins = None
4342+
43294343
if isinstance(norm, mcolors.LogNorm):
43304344
if (accum == 0).any():
4331-
# make sure we have not zeros
4345+
# make sure we have no zeros
43324346
accum += 1
43334347

43344348
# autoscale the norm with curren accum values if it hasn't
@@ -4337,20 +4351,14 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
43374351
if norm.vmin is None and norm.vmax is None:
43384352
norm.autoscale(accum)
43394353

4340-
# Transform accum if needed
4341-
if bins == 'log':
4342-
accum = np.log10(accum + 1)
4343-
elif bins is not None:
4354+
if bins is not None:
43444355
if not iterable(bins):
43454356
minimum, maximum = min(accum), max(accum)
43464357
bins -= 1 # one less edge than bins
43474358
bins = minimum + (maximum - minimum) * np.arange(bins) / bins
43484359
bins = np.sort(bins)
43494360
accum = bins.searchsorted(accum)
43504361

4351-
if norm is not None and not isinstance(norm, mcolors.Normalize):
4352-
raise ValueError(
4353-
"'norm' must be an instance of 'mcolors.Normalize'")
43544362
collection.set_array(accum)
43554363
collection.set_cmap(cmap)
43564364
collection.set_norm(norm)

lib/matplotlib/tests/test_axes.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -858,18 +858,18 @@ def __init__(self, x, y):
858858

859859

860860
@image_comparison(baseline_images=['hexbin_log'],
861-
remove_text=True,
862-
extensions=['png'])
861+
extensions=['png'], style='mpl20')
863862
def test_hexbin_log():
864-
# Issue #1636
865-
np.random.seed(0)
863+
# Issue #1636 (and also test log scaled colorbar)
864+
np.random.seed(19680801)
866865
n = 100000
867866
x = np.random.standard_normal(n)
868867
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
869868
y = np.power(2, y * 0.5)
870869

871870
fig, ax = plt.subplots()
872-
ax.hexbin(x, y, yscale='log')
871+
h = ax.hexbin(x, y, yscale='log', bins='log')
872+
plt.colorbar(h)
873873

874874

875875
def test_inverted_limits():

0 commit comments

Comments
 (0)