Skip to content

Commit 90c434e

Browse files
committed
Make logscale bar autolimits more consistents.
The bottom limit of log-scaled plots now defaults to applying normal margins (possibly with null limits expansion) to the data limits, rather than being hardcoded to 1/log_base. See changelog. Delete two tests that asserted that the lower limit was at 1/log_base.
1 parent 63d96d2 commit 90c434e

File tree

7 files changed

+29
-3634
lines changed

7 files changed

+29
-3634
lines changed
Lines changed: 10 additions & 0 deletions
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

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,20 +2295,12 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
22952295
label = kwargs.pop('label', '')
22962296
tick_labels = kwargs.pop('tick_label', None)
22972297

2298-
adjust_ylim = False
2299-
adjust_xlim = False
2300-
23012298
y = bottom # Matches barh call signature.
23022299
if orientation == 'vertical':
2303-
if bottom is None:
2304-
if self.get_yscale() == 'log':
2305-
adjust_ylim = True
2300+
if y is None:
23062301
y = 0
2307-
23082302
elif orientation == 'horizontal':
23092303
if x is None:
2310-
if self.get_xscale() == 'log':
2311-
adjust_xlim = True
23122304
x = 0
23132305

23142306
if orientation == 'vertical':
@@ -2421,21 +2413,6 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
24212413
else:
24222414
errorbar = None
24232415

2424-
if adjust_xlim:
2425-
xmin, xmax = self.dataLim.intervalx
2426-
xmin = min(w for w in width if w > 0)
2427-
if xerr is not None:
2428-
xmin = xmin - np.max(xerr)
2429-
xmin = max(xmin * 0.9, 1e-100)
2430-
self.dataLim.intervalx = (xmin, xmax)
2431-
2432-
if adjust_ylim:
2433-
ymin, ymax = self.dataLim.intervaly
2434-
ymin = min(h for h in height if h > 0)
2435-
if yerr is not None:
2436-
ymin = ymin - np.max(yerr)
2437-
ymin = max(ymin * 0.9, 1e-100)
2438-
self.dataLim.intervaly = (ymin, ymax)
24392416
self._request_autoscale_view()
24402417

24412418
bar_container = BarContainer(patches, errorbar, label=label)
@@ -6738,30 +6715,8 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
67386715
if log:
67396716
if orientation == 'horizontal':
67406717
self.set_xscale('log', nonposx='clip')
6741-
logbase = self.xaxis._scale.base
67426718
else: # orientation == 'vertical'
67436719
self.set_yscale('log', nonposy='clip')
6744-
logbase = self.yaxis._scale.base
6745-
6746-
# Setting a minimum of 0 results in problems for log plots
6747-
if np.min(bottom) > 0:
6748-
minimum = np.min(bottom)
6749-
elif density or weights is not None:
6750-
# For data that is normed to form a probability density,
6751-
# set to minimum data value / logbase
6752-
# (gives 1 full tick-label unit for the lowest filled bin)
6753-
ndata = np.array(tops)
6754-
minimum = (np.min(ndata[ndata > 0])) / logbase
6755-
else:
6756-
# For non-normed (density = False) data,
6757-
# set the min to 1 / log base,
6758-
# again so that there is 1 full tick-label unit
6759-
# for the lowest bin
6760-
minimum = 1.0 / logbase
6761-
6762-
y[0], y[-1] = minimum, minimum
6763-
else:
6764-
minimum = 0
67656720

67666721
if align == 'left':
67676722
x -= 0.5*(bins[1]-bins[0])
@@ -6782,8 +6737,6 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
67826737
# set the top of this polygon
67836738
y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom,
67846739
m + bottom)
6785-
if log:
6786-
y[y < minimum] = minimum
67876740
if orientation == 'horizontal':
67886741
xvals.append(y.copy())
67896742
yvals.append(x.copy())
@@ -6806,9 +6759,9 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
68066759
for patch_list in patches:
68076760
for patch in patch_list:
68086761
if orientation == 'vertical':
6809-
patch.sticky_edges.y.append(minimum)
6762+
patch.sticky_edges.y.append(0)
68106763
elif orientation == 'horizontal':
6811-
patch.sticky_edges.x.append(minimum)
6764+
patch.sticky_edges.x.append(0)
68126765

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

0 commit comments

Comments
 (0)