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

Commit6a2d157

Browse files
authored
Merge pull requestmatplotlib#21039 from dstansby/hexbin-marginal
Fix `hexbin` marginals and log scaling
2 parents5a4fe4a +c8f8002 commit6a2d157

File tree

4 files changed

+51
-47
lines changed

4 files changed

+51
-47
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
hexbin with a log norm
2+
----------------------
3+
`~.axes.Axes.hexbin` no longer (incorrectly) adds 1 to every bin value if a
4+
log norm is being used.

‎lib/matplotlib/axes/_axes.py‎

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4589,6 +4589,11 @@ def reduce_C_function(C: array) -> float
45894589
# Count the number of data in each hexagon
45904590
x=np.array(x,float)
45914591
y=np.array(y,float)
4592+
4593+
ifmarginals:
4594+
xorig=x.copy()
4595+
yorig=y.copy()
4596+
45924597
ifxscale=='log':
45934598
ifnp.any(x<=0.0):
45944599
raiseValueError("x contains non-positive values, so can not"
@@ -4617,10 +4622,6 @@ def reduce_C_function(C: array) -> float
46174622
sx= (xmax-xmin)/nx
46184623
sy= (ymax-ymin)/ny
46194624

4620-
ifmarginals:
4621-
xorig=x.copy()
4622-
yorig=y.copy()
4623-
46244625
x= (x-xmin)/sx
46254626
y= (y-ymin)/sy
46264627
ix1=np.round(x).astype(int)
@@ -4746,11 +4747,6 @@ def reduce_C_function(C: array) -> float
47464747
vmin=vmax=None
47474748
bins=None
47484749

4749-
ifisinstance(norm,mcolors.LogNorm):
4750-
if (accum==0).any():
4751-
# make sure we have no zeros
4752-
accum+=1
4753-
47544750
# autoscale the norm with current accum values if it hasn't
47554751
# been set
47564752
ifnormisnotNone:
@@ -4781,40 +4777,42 @@ def reduce_C_function(C: array) -> float
47814777
ifnotmarginals:
47824778
returncollection
47834779

4780+
# Process marginals
47844781
ifCisNone:
47854782
C=np.ones(len(x))
47864783

4787-
defcoarse_bin(x,y,coarse):
4788-
ind=coarse.searchsorted(x).clip(0,len(coarse)-1)
4789-
mus=np.zeros(len(coarse))
4790-
foriinrange(len(coarse)):
4791-
yi=y[ind==i]
4784+
defcoarse_bin(x,y,bin_edges):
4785+
"""
4786+
Sort x-values into bins defined by *bin_edges*, then for all the
4787+
corresponding y-values in each bin use *reduce_c_function* to
4788+
compute the bin value.
4789+
"""
4790+
nbins=len(bin_edges)-1
4791+
# Sort x-values into bins
4792+
bin_idxs=np.searchsorted(bin_edges,x)-1
4793+
mus=np.zeros(nbins)*np.nan
4794+
foriinrange(nbins):
4795+
# Get y-values for each bin
4796+
yi=y[bin_idxs==i]
47924797
iflen(yi)>0:
4793-
mu=reduce_C_function(yi)
4794-
else:
4795-
mu=np.nan
4796-
mus[i]=mu
4798+
mus[i]=reduce_C_function(yi)
47974799
returnmus
47984800

4799-
coarse=np.linspace(xmin,xmax,gridsize)
4801+
ifxscale=='log':
4802+
bin_edges=np.geomspace(xmin,xmax,nx+1)
4803+
else:
4804+
bin_edges=np.linspace(xmin,xmax,nx+1)
4805+
xcoarse=coarse_bin(xorig,C,bin_edges)
48004806

4801-
xcoarse=coarse_bin(xorig,C,coarse)
4802-
valid=~np.isnan(xcoarse)
48034807
verts,values= [], []
4804-
fori,valinenumerate(xcoarse):
4805-
thismin=coarse[i]
4806-
ifi<len(coarse)-1:
4807-
thismax=coarse[i+1]
4808-
else:
4809-
thismax=thismin+np.diff(coarse)[-1]
4810-
4811-
ifnotvalid[i]:
4808+
forbin_left,bin_right,valinzip(
4809+
bin_edges[:-1],bin_edges[1:],xcoarse):
4810+
ifnp.isnan(val):
48124811
continue
4813-
4814-
verts.append([(thismin,0),
4815-
(thismin,0.05),
4816-
(thismax,0.05),
4817-
(thismax,0)])
4812+
verts.append([(bin_left,0),
4813+
(bin_left,0.05),
4814+
(bin_right,0.05),
4815+
(bin_right,0)])
48184816
values.append(val)
48194817

48204818
values=np.array(values)
@@ -4829,20 +4827,21 @@ def coarse_bin(x, y, coarse):
48294827
hbar.update(kwargs)
48304828
self.add_collection(hbar,autolim=False)
48314829

4832-
coarse=np.linspace(ymin,ymax,gridsize)
4833-
ycoarse=coarse_bin(yorig,C,coarse)
4834-
valid=~np.isnan(ycoarse)
4830+
ifyscale=='log':
4831+
bin_edges=np.geomspace(ymin,ymax,2*ny+1)
4832+
else:
4833+
bin_edges=np.linspace(ymin,ymax,2*ny+1)
4834+
ycoarse=coarse_bin(yorig,C,bin_edges)
4835+
48354836
verts,values= [], []
4836-
fori,valinenumerate(ycoarse):
4837-
thismin=coarse[i]
4838-
ifi<len(coarse)-1:
4839-
thismax=coarse[i+1]
4840-
else:
4841-
thismax=thismin+np.diff(coarse)[-1]
4842-
ifnotvalid[i]:
4837+
forbin_bottom,bin_top,valinzip(
4838+
bin_edges[:-1],bin_edges[1:],ycoarse):
4839+
ifnp.isnan(val):
48434840
continue
4844-
verts.append([(0,thismin), (0.0,thismax),
4845-
(0.05,thismax), (0.05,thismin)])
4841+
verts.append([(0,bin_bottom),
4842+
(0,bin_top),
4843+
(0.05,bin_top),
4844+
(0.05,bin_bottom)])
48464845
values.append(val)
48474846

48484847
values=np.array(values)
14.5 KB
Loading

‎lib/matplotlib/tests/test_axes.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,8 @@ def test_hexbin_log():
781781
y=np.power(2,y*0.5)
782782

783783
fig,ax=plt.subplots()
784-
h=ax.hexbin(x,y,yscale='log',bins='log')
784+
h=ax.hexbin(x,y,yscale='log',bins='log',
785+
marginals=True,reduce_C_function=np.sum)
785786
plt.colorbar(h)
786787

787788

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp