Skip to content

Commit 662bb8c

Browse files
authored
Merge pull request #14581 from anntzer/barlog
Make logscale bar/hist autolimits more consistents.
2 parents e4dbfb5 + c1ea241 commit 662bb8c

File tree

7 files changed

+29
-3634
lines changed

7 files changed

+29
-3634
lines changed
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
log-scale bar() / hist() autolimits change
2+
``````````````````````````````````````````
3+
4+
The autolimits computation in `~.Axes.bar` and `~.Axes.hist` when the axes
5+
already uses log-scale has changed to match the computation when the axes is
6+
switched to log-scale after the call to `~.Axes.bar` and `~.Axes.hist`, and
7+
when calling ``bar(..., log=True)`` / ``hist(..., log=True)``: if there are
8+
at least two different bar heights, add the normal axes margins to them (in
9+
log-scale); if there is only a single bar height, expand the axes limits by one
10+
order of magnitude around it and then apply axes margins.

lib/matplotlib/axes/_axes.py

+3-50
Original file line numberDiff line numberDiff line change
@@ -2303,20 +2303,12 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
23032303
label = kwargs.pop('label', '')
23042304
tick_labels = kwargs.pop('tick_label', None)
23052305

2306-
adjust_ylim = False
2307-
adjust_xlim = False
2308-
23092306
y = bottom # Matches barh call signature.
23102307
if orientation == 'vertical':
2311-
if bottom is None:
2312-
if self.get_yscale() == 'log':
2313-
adjust_ylim = True
2308+
if y is None:
23142309
y = 0
2315-
23162310
elif orientation == 'horizontal':
23172311
if x is None:
2318-
if self.get_xscale() == 'log':
2319-
adjust_xlim = True
23202312
x = 0
23212313

23222314
if orientation == 'vertical':
@@ -2429,21 +2421,6 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
24292421
else:
24302422
errorbar = None
24312423

2432-
if adjust_xlim:
2433-
xmin, xmax = self.dataLim.intervalx
2434-
xmin = min(w for w in width if w > 0)
2435-
if xerr is not None:
2436-
xmin = xmin - np.max(xerr)
2437-
xmin = max(xmin * 0.9, 1e-100)
2438-
self.dataLim.intervalx = (xmin, xmax)
2439-
2440-
if adjust_ylim:
2441-
ymin, ymax = self.dataLim.intervaly
2442-
ymin = min(h for h in height if h > 0)
2443-
if yerr is not None:
2444-
ymin = ymin - np.max(yerr)
2445-
ymin = max(ymin * 0.9, 1e-100)
2446-
self.dataLim.intervaly = (ymin, ymax)
24472424
self._request_autoscale_view()
24482425

24492426
bar_container = BarContainer(patches, errorbar, label=label)
@@ -6757,30 +6734,8 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
67576734
if log:
67586735
if orientation == 'horizontal':
67596736
self.set_xscale('log', nonposx='clip')
6760-
logbase = self.xaxis._scale.base
67616737
else: # orientation == 'vertical'
67626738
self.set_yscale('log', nonposy='clip')
6763-
logbase = self.yaxis._scale.base
6764-
6765-
# Setting a minimum of 0 results in problems for log plots
6766-
if np.min(bottom) > 0:
6767-
minimum = np.min(bottom)
6768-
elif density or weights is not None:
6769-
# For data that is normed to form a probability density,
6770-
# set to minimum data value / logbase
6771-
# (gives 1 full tick-label unit for the lowest filled bin)
6772-
ndata = np.array(tops)
6773-
minimum = (np.min(ndata[ndata > 0])) / logbase
6774-
else:
6775-
# For non-normed (density = False) data,
6776-
# set the min to 1 / log base,
6777-
# again so that there is 1 full tick-label unit
6778-
# for the lowest bin
6779-
minimum = 1.0 / logbase
6780-
6781-
y[0], y[-1] = minimum, minimum
6782-
else:
6783-
minimum = 0
67846739

67856740
if align == 'left':
67866741
x -= 0.5*(bins[1]-bins[0])
@@ -6801,8 +6756,6 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
68016756
# set the top of this polygon
68026757
y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom,
68036758
m + bottom)
6804-
if log:
6805-
y[y < minimum] = minimum
68066759
if orientation == 'horizontal':
68076760
xvals.append(y.copy())
68086761
yvals.append(x.copy())
@@ -6825,9 +6778,9 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
68256778
for patch_list in patches:
68266779
for patch in patch_list:
68276780
if orientation == 'vertical':
6828-
patch.sticky_edges.y.append(minimum)
6781+
patch.sticky_edges.y.append(0)
68296782
elif orientation == 'horizontal':
6830-
patch.sticky_edges.x.append(minimum)
6783+
patch.sticky_edges.x.append(0)
68316784

68326785
# we return patches, so put it back in the expected order
68336786
patches.reverse()
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)