@@ -4921,11 +4921,10 @@ def make_iterable(x):
4921
4921
if orientation == 'vertical' :
4922
4922
self ._process_unit_info (xdata = left , ydata = height , kwargs = kwargs )
4923
4923
if log :
4924
- self .set_yscale ('log' )
4924
+ self .set_yscale ('log' , nonposy = 'clip' )
4925
4925
# size width and bottom according to length of left
4926
4926
if _bottom is None :
4927
4927
if self .get_yscale () == 'log' :
4928
- bottom = [1e-100 ]
4929
4928
adjust_ylim = True
4930
4929
else :
4931
4930
bottom = [0 ]
@@ -4937,11 +4936,10 @@ def make_iterable(x):
4937
4936
elif orientation == 'horizontal' :
4938
4937
self ._process_unit_info (xdata = width , ydata = bottom , kwargs = kwargs )
4939
4938
if log :
4940
- self .set_xscale ('log' )
4939
+ self .set_xscale ('log' , nonposx = 'clip' )
4941
4940
# size left and height according to length of bottom
4942
4941
if _left is None :
4943
4942
if self .get_xscale () == 'log' :
4944
- left = [1e-100 ]
4945
4943
adjust_xlim = True
4946
4944
else :
4947
4945
left = [0 ]
@@ -8218,6 +8216,11 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8218
8216
raise ValueError (
8219
8217
"orientation kwarg %s is not recognized" % orientation )
8220
8218
8219
+ if kwargs .get ('width' ) is not None :
8220
+ raise mplDeprecation (
8221
+ 'hist now uses the rwidth to give relative width '
8222
+ 'and not absolute width' )
8223
+
8221
8224
if histtype == 'barstacked' and not stacked :
8222
8225
stacked = True
8223
8226
@@ -8233,9 +8236,9 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8233
8236
else :
8234
8237
raise ValueError ("x must be 1D or 2D" )
8235
8238
if x .shape [1 ] < x .shape [0 ]:
8236
- warnings .warn ('2D hist input should be nsamples x '
8237
- ' nvariables;\n this looks transposed '
8238
- ' (shape is %d x %d)' % x .shape [::- 1 ])
8239
+ warnings .warn (
8240
+ '2D hist input should be nsamples x nvariables;\n '
8241
+ 'this looks transposed (shape is %d x %d)' % x .shape [::- 1 ])
8239
8242
else :
8240
8243
# multiple hist with data of different length
8241
8244
x = [np .asarray (xi ) for xi in x ]
@@ -8270,7 +8273,7 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8270
8273
raise ValueError (
8271
8274
'weights should have the same shape as x' )
8272
8275
else :
8273
- w = [None ] * nx
8276
+ w = [None ]* nx
8274
8277
8275
8278
# Save autoscale state for later restoration; turn autoscaling
8276
8279
# off so we can do it all a single time at the end, instead
@@ -8285,7 +8288,7 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8285
8288
8286
8289
# Check whether bins or range are given explicitly. In that
8287
8290
# case use those values for autoscaling.
8288
- binsgiven = (cbook .iterable (bins ) or bin_range != None )
8291
+ binsgiven = (cbook .iterable (bins ) or bin_range is not None )
8289
8292
8290
8293
# If bins are not specified either explicitly or via range,
8291
8294
# we need to figure out the range required for all datasets,
@@ -8304,16 +8307,13 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8304
8307
hist_kwargs = dict (range = bin_range )
8305
8308
8306
8309
n = []
8307
- mlast = None
8308
- # reversed order is necessary so when stacking histogram, first
8309
- # dataset is on top if histogram isn't stacked, this doesn't make any
8310
- # difference
8311
- for i in reversed (xrange (nx )):
8310
+ mlast = bottom
8311
+ for i in xrange (nx ):
8312
8312
# this will automatically overwrite bins,
8313
8313
# so that each histogram uses the same bins
8314
8314
m , bins = np .histogram (x [i ], bins , weights = w [i ], ** hist_kwargs )
8315
8315
if mlast is None :
8316
- mlast = np .zeros (len (bins ) - 1 , m .dtype )
8316
+ mlast = np .zeros (len (bins )- 1 , m .dtype )
8317
8317
if normed :
8318
8318
db = np .diff (bins )
8319
8319
m = (m .astype (float ) / db ) / m .sum ()
@@ -8322,8 +8322,6 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8322
8322
mlast [:] = m
8323
8323
n .append (m )
8324
8324
8325
-
8326
-
8327
8325
if cumulative :
8328
8326
slc = slice (None )
8329
8327
if cbook .is_numlike (cumulative ) and cumulative < 0 :
@@ -8334,8 +8332,6 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8334
8332
else :
8335
8333
n = [m [slc ].cumsum ()[slc ] for m in n ]
8336
8334
8337
- n .reverse () # put them back in the right order
8338
-
8339
8335
patches = []
8340
8336
8341
8337
if histtype .startswith ('bar' ):
@@ -8349,21 +8345,20 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8349
8345
dr = 1.0
8350
8346
8351
8347
if histtype == 'bar' and not stacked :
8352
- width = dr * totwidth / nx
8348
+ width = dr * totwidth / nx
8353
8349
dw = width
8354
8350
8355
8351
if nx > 1 :
8356
- boffset = - 0.5 * dr * totwidth * (1.0 - 1.0 / nx )
8352
+ boffset = - 0.5 * dr * totwidth * (1.0 - 1.0 / nx )
8357
8353
else :
8358
8354
boffset = 0.0
8359
8355
stacked = False
8360
8356
elif histtype == 'barstacked' or stacked :
8361
- width = dr * totwidth
8357
+ width = dr * totwidth
8362
8358
boffset , dw = 0.0 , 0.0
8363
8359
8364
8360
if align == 'mid' or align == 'edge' :
8365
- boffset += 0.5 * totwidth
8366
-
8361
+ boffset += 0.5 * totwidth
8367
8362
elif align == 'right' :
8368
8363
boffset += totwidth
8369
8364
@@ -8373,31 +8368,34 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8373
8368
_barfunc = self .bar
8374
8369
8375
8370
for m , c in zip (n , color ):
8376
- patch = _barfunc (bins [:- 1 ] + boffset , m , width ,
8371
+ if bottom is None :
8372
+ bottom = np .zeros (len (m ), np .float )
8373
+ if stacked :
8374
+ height = m - bottom
8375
+ else :
8376
+ height = m
8377
+ patch = _barfunc (bins [:- 1 ]+ boffset , height , width ,
8377
8378
align = 'center' , log = log ,
8378
8379
color = c , bottom = bottom )
8379
8380
patches .append (patch )
8381
+ if stacked :
8382
+ bottom [:] = m
8380
8383
boffset += dw
8381
8384
8382
8385
elif histtype .startswith ('step' ):
8383
- x = np .zeros (2 * len (bins ), np .float )
8384
- y = np .zeros (2 * len (bins ), np .float )
8385
-
8386
- x [0 ::2 ], x [1 ::2 ] = bins , bins
8387
-
8388
- minimum = np .min (n )
8386
+ # these define the perimeter of the polygon
8387
+ x = np .zeros (4 * len (bins ) - 3 , np .float )
8388
+ y = np .zeros (4 * len (bins ) - 3 , np .float )
8389
8389
8390
- if align == 'left' or align == 'center' :
8391
- x -= 0.5 * (bins [1 ] - bins [0 ])
8392
- elif align == 'right' :
8393
- x += 0.5 * (bins [1 ] - bins [0 ])
8390
+ x [0 :2 * len (bins )- 1 :2 ], x [1 :2 * len (bins )- 1 :2 ] = bins , bins [:- 1 ]
8391
+ x [2 * len (bins )- 1 :] = x [1 :2 * len (bins )- 1 ][::- 1 ]
8394
8392
8395
8393
if log :
8396
8394
if orientation == 'horizontal' :
8397
- self .set_xscale ('log' )
8395
+ self .set_xscale ('log' , nonposx = 'clip' )
8398
8396
logbase = self .xaxis ._scale .base
8399
8397
else : # orientation == 'vertical'
8400
- self .set_yscale ('log' )
8398
+ self .set_yscale ('log' , nonposy = 'clip' )
8401
8399
logbase = self .yaxis ._scale .base
8402
8400
8403
8401
# Setting a minimum of 0 results in problems for log plots
@@ -8407,47 +8405,71 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8407
8405
ndata = np .array (n )
8408
8406
minimum = (np .min (ndata [ndata > 0 ])) / logbase
8409
8407
else :
8410
- # For non-normed data, set the min to log base, again so
8411
- # that there is 1 full tick-label unit for the lowest bin
8408
+ # For non-normed data, set the min to log base,
8409
+ # again so that there is 1 full tick-label unit
8410
+ # for the lowest bin
8412
8411
minimum = 1.0 / logbase
8413
8412
8414
8413
y [0 ], y [- 1 ] = minimum , minimum
8415
8414
else :
8416
8415
minimum = np .min (bins )
8417
8416
8417
+ if align == 'left' or align == 'center' :
8418
+ x -= 0.5 * (bins [1 ]- bins [0 ])
8419
+ elif align == 'right' :
8420
+ x += 0.5 * (bins [1 ]- bins [0 ])
8421
+
8418
8422
# If fill kwarg is set, it will be passed to the patch collection,
8419
8423
# overriding this
8420
8424
fill = (histtype == 'stepfilled' )
8421
8425
8422
- for m , c in zip (n , color ):
8423
- y [1 :- 1 :2 ], y [2 ::2 ] = m , m
8426
+ xvals , yvals = [], []
8427
+ for m in n :
8428
+ # starting point for drawing polygon
8429
+ y [0 ] = y [- 1 ]
8430
+ # top of the previous polygon becomes the bottom
8431
+ y [2 * len (bins )- 1 :] = y [1 :2 * len (bins )- 1 ][::- 1 ]
8432
+ # set the top of this polygon
8433
+ y [1 :2 * len (bins )- 1 :2 ], y [2 :2 * len (bins ):2 ] = m , m
8424
8434
if log :
8425
8435
y [y < minimum ] = minimum
8426
8436
if orientation == 'horizontal' :
8427
8437
x , y = y , x
8428
8438
8439
+ xvals .append (x .copy ())
8440
+ yvals .append (y .copy ())
8441
+
8442
+ # add patches in reverse order so that when stacking,
8443
+ # items lower in the stack are plottted on top of
8444
+ # items higher in the stack
8445
+ for x , y , c in reversed (zip (xvals , yvals , color )):
8429
8446
if fill :
8430
8447
patches .append (self .fill (x , y ,
8431
- closed = False , facecolor = c ))
8448
+ closed = False ,
8449
+ facecolor = c ))
8432
8450
else :
8433
8451
patches .append (self .fill (x , y ,
8434
- closed = False , edgecolor = c , fill = False ))
8452
+ closed = False , edgecolor = c ,
8453
+ fill = False ))
8454
+
8455
+ # we return patches, so put it back in the expected order
8456
+ patches .reverse ()
8435
8457
8436
8458
# adopted from adjust_x/ylim part of the bar method
8437
8459
if orientation == 'horizontal' :
8438
- xmin0 = max (_saved_bounds [0 ] * 0.9 , minimum )
8460
+ xmin0 = max (_saved_bounds [0 ]* 0.9 , minimum )
8439
8461
xmax = self .dataLim .intervalx [1 ]
8440
8462
for m in n :
8441
- xmin = np .amin (m [m != 0 ]) # filter out the 0 height bins
8442
- xmin = max (xmin * 0.9 , minimum )
8463
+ xmin = np .amin (m [m != 0 ]) # filter out the 0 height bins
8464
+ xmin = max (xmin * 0.9 , minimum )
8443
8465
xmin = min (xmin0 , xmin )
8444
8466
self .dataLim .intervalx = (xmin , xmax )
8445
8467
elif orientation == 'vertical' :
8446
- ymin0 = max (_saved_bounds [1 ] * 0.9 , minimum )
8468
+ ymin0 = max (_saved_bounds [1 ]* 0.9 , minimum )
8447
8469
ymax = self .dataLim .intervaly [1 ]
8448
8470
for m in n :
8449
- ymin = np .amin (m [m != 0 ]) # filter out the 0 height bins
8450
- ymin = max (ymin * 0.9 , minimum )
8471
+ ymin = np .amin (m [m != 0 ]) # filter out the 0 height bins
8472
+ ymin = max (ymin * 0.9 , minimum )
8451
8473
ymin = min (ymin0 , ymin )
8452
8474
self .dataLim .intervaly = (ymin , ymax )
8453
8475
@@ -8458,8 +8480,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8458
8480
elif is_sequence_of_strings (label ):
8459
8481
labels = list (label )
8460
8482
else :
8461
- raise ValueError ('invalid label: must be string or sequence of '
8462
- ' strings' )
8483
+ raise ValueError (
8484
+ 'invalid label: must be string or sequence of strings' )
8463
8485
8464
8486
if len (labels ) < nx :
8465
8487
labels += [None ] * (nx - len (labels ))
@@ -8479,11 +8501,11 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
8479
8501
8480
8502
if binsgiven :
8481
8503
if orientation == 'vertical' :
8482
- self .update_datalim ([( bins [ 0 ], 0 ), ( bins [ - 1 ], 0 )],
8483
- updatey = False )
8504
+ self .update_datalim (
8505
+ [( bins [ 0 ], 0 ), ( bins [ - 1 ], 0 )], updatey = False )
8484
8506
else :
8485
- self .update_datalim ([( 0 , bins [ 0 ]), ( 0 , bins [ - 1 ])],
8486
- updatex = False )
8507
+ self .update_datalim (
8508
+ [( 0 , bins [ 0 ]), ( 0 , bins [ - 1 ])], updatex = False )
8487
8509
8488
8510
self .set_autoscalex_on (_saved_autoscalex )
8489
8511
self .set_autoscaley_on (_saved_autoscaley )
0 commit comments