Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add stacked kwarg to hist and implement stacked hists for step histtype #847

Merged
merged 6 commits into from

8 participants

@neggert

This PR addresses matplotlib/matplotlib#831. The main goal was to implement stacked histograms when using the step or stepfilled histtypes. Rather than add new histtypes as with the barstacked histtype, a new stacked kwarg was added. This kwarg behaves as expected for all four histtypes.

I've added an example showing what happens when histtype="stepfilled", stacked=True. Here is the output of the new example:

stacked histogram example

@mdboom
Owner

Sorry this PR has languished for so long. @WeatherGod: Do you have any comments on this approach in relation to the more general plans for "stacked" plots.

And I will make my usual comment that it's great to see an example -- we should also have a unit test for this.

@WeatherGod
Collaborator

I will likely be at the 2012 SciPy conference. I am sure that we can discuss issues such as this and develop some sort of over-arching design plan.

@neggert

Sorry for the delay, I was taking my PhD candidacy exam, so I didn't have time to work on this.

I added a test for the new functionality. Incidentally, I don't think there are any other tests for for axes.hist. Maybe in the future, I'll write some.

Did any of the higher-ups get a chance to discuss the fate of stacked plots at Scipy2012?

@WeatherGod
Collaborator

I totally understand the need to focus on the candidacy exam. At SciPy2012, many things got discussed, but not that, unfortunately. Maybe a discussion should be started on the mailing list?

@WeatherGod
Collaborator

And it looks like you need to do a rebase. Make sure that your test images are based on the rebased version as there may have been changes to small details such as text rendering or line anti-aliasing.

@neggert

I've rebased and squashed it down to 1 commit. I also sent around a message to matplotlib-devel trying to start a conversation about the general idea of stacked-ness. Please reply there if you interested in the more general issues of how to approach this problem.

@neggert

So I haven't gotten any replies to the message I sent to matplotlib-devel. Any thoughts on how to proceed?

lib/matplotlib/axes.py
((5 lines not shown))
for i in xrange(nx):
# this will automatically overwrite bins,
# so that each histogram uses the same bins
m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
+ if mlast == None :
@efiring Owner
efiring added a note

Tiny style point: please delete space between condition and colon, here and below.

@pelson Collaborator
pelson added a note

Tiny style point #3: it is preferable to use obj is None (PEP8: "Comparisons to singletons like None should always be done with is or is not, never the equality operators.").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@efiring
Owner

I'm sorry you have been having a hard time getting responses.
I haven't looked very closely, and in particular I have not tried out this changeset on my machine, but offhand it looks sensible. Unfortunately, I have no idea what ideas have been floating around regarding general "stackedness", but it is hard to imagine what would conflict with your changeset. And also unfortunately, yet another rebase will be needed. Whenever it is decided that this will go in, some additions to the CHANGELOG and other documentation will be in order.

@neggert

Just cleaned up a few style issues and rebased.

lib/matplotlib/axes.py
@@ -7919,6 +7927,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
# multiple hist with data of different length
x = [np.asarray(xi) for xi in x]
+ x = x[::-1] # reverse datasets for caculating stacked hist
@efiring Owner
efiring added a note

Why do you reverse the order? This seems like an unnecessary change from the previous behavior.

@neggert
neggert added a note

In the loop starting on line 8002, I want to iterate over the datasets in reverse order so that the first input goes on top. Note that I put them back in the correct order at line 8027.

Now that you point this out, it might be better to reverse the loop than the vector. This would result in the first dataset being plotted at the bottom, which might be better.

@neggert
neggert added a note

I've put up the alternative. This is probably the minimally invasive way to do it.

P.S. I was mistaken about the first dataset going at the bottom. That would require more extensive changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ndawe

Will this be merged in soon? Looking forward to this feature!

For now I am using many complicated fill_betweens... For me, this is one of the few remaining issues with matplotlib that prevent me from fully abandoning ROOT for plotting. I've been developing an interface between ROOT and matplotlib in rootpy:

https://github.com/rootpy/rootpy/blob/master/rootpy/plotting/root2matplotlib.py

but ROOT plots stacked histograms like this "stacked stepfilled" feature. In matplotlib, stacked bar plots can have very thin white lines between bars in vector-based formats, which I find unappealing.

@dmcdougall
Collaborator

@ndawe If you don't mind installing from source, it is possible to use this changeset without it having been merged into the main codebase. Add a new git remote to point to the repo of @neggert. Then you can checkout his branch and install :)

If you need help with any of this, let me know.

At least now you don't have to wait for it to be merged.

@WeatherGod
Collaborator

The only thing left to do is to update pyplot.py using the boilerplate.py script in the mpl root directory and to add a note to docs/users/whats_new.rst.

Note, I am not sure if the feature freeze has happened yet or not, so it is possible this may get deferred to the next release.

@mdboom
Owner

I think we can still get this in to 1.2 by the end of the week, if @WeatherGod's tiny fixes are addressed.

@neggert

Done. The changes made by boilerplate.py included a bunch of whitespace changes. I left them out of the commit, but I can put them back if there was some good reason for them.

@travisbot

This pull request fails (merged 014fe4c1 into 94c53e1).

@travisbot

This pull request fails (merged 9f6c10da into 94c53e1).

@neggert

Rebased as well.

@travisbot

This pull request fails (merged 77c5978 into 0f9f85f).

doc/users/whats_new.rst
@@ -127,6 +127,16 @@ local intensity of the vector field.
.. plot:: mpl_examples/pylab_examples/streamplot_demo.py
+
+New hist functionality
+----------------------
+
+Nic Eggert added a new `stack kwarg to :meth:`~matplotlib.pyplot.hist` that
@dmcdougall Collaborator

Should stack have a closing backtick?

@dmcdougall Collaborator

Also, isn't the kwarg called stacked, not stack?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@travisbot

This pull request fails (merged 242ecac into 0f9f85f).

@WeatherGod WeatherGod commented on the diff
lib/matplotlib/axes.py
((9 lines not shown))
# this will automatically overwrite bins,
# so that each histogram uses the same bins
m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
+ if mlast is None:
+ mlast = np.zeros(len(bins)-1, np.int)
@WeatherGod Collaborator

Just a thought... are we guaranteed that bins will have a non-zero length? If not, then it would be a good idea to catch the length-zero case and raise a descriptive exception.

@neggert
neggert added a note

The bins argument to np.histogram takes either the number of bins or an array of bin edges.

I just played around a little, and I don't think it's possible for np.histogram to return a zero-length array of bin edges. It raises an exception if one tries to set bins=0

In fact, the only way I can get it to return anything less than a length-2 array is by explicitly passing only one bin edge. This will obviously result in some strange behavior, but that's a pretty edge case. If np.histogram doesn't raise an exception for that, I don't think we should, either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@neggert

Anyone have any idea why the bot keeps telling me the PR fails? I've rebased onto the latest version of master.

@WeatherGod
Collaborator

Don't worry too much about the Travisbot right now, we are still working out the kinks. As for np.histogram(), I have a vague recollection of it being possible for it to return empty arrays in bad situations, which was later fixed. But it was an extreme edge case that I am not sure is possible to trigger here anyway.

@WeatherGod
Collaborator

However, the logs do speak of stacked plots failing (not yours, but some of the originals). Maybe worth investigating further.

@mdboom
Owner

I'm not seeing any additional test failures with this branch on my local machine. Are others (ignoring Travis, since it seems to throw a lot of false positive failures). What's left to be done on this? Anything?

@neggert

I think mine looks fine. Here's the test log if someone more knowledgeable wants to look at it: https://gist.github.com/3691954. If those look good, IMO, this is good to go.

@mdboom mdboom merged commit 634f02d into matplotlib:master
@mdboom
Owner

This may have introduced #1679: @neggert: Do you have any thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
11 doc/users/whats_new.rst
@@ -127,6 +127,17 @@ local intensity of the vector field.
.. plot:: mpl_examples/pylab_examples/streamplot_demo.py
+
+New hist functionality
+----------------------
+
+Nic Eggert added a new `stacked` kwarg to :meth:`~matplotlib.pyplot.hist` that
+allows creation of stacked histograms using any of the histogram types.
+Previously, this functionality was only available by using the `barstacked`
+histogram type. Now, when `stacked=True` is passed to the function, any of the
+histogram types can be stacked. The `barstacked` histogram type retains its
+previous functionality for backwards compatibility.
+
Updated shipped dependencies
----------------------------
View
14 examples/pylab_examples/histogram_demo_extended.py
@@ -82,7 +82,19 @@
#
P.figure()
-n, bins, patches = P.hist(x, 10, normed=1, histtype='barstacked')
+n, bins, patches = P.hist(x, 10, normed=1, histtype='bar', stacked=True)
+
+P.show()
+
+#
+# we can also stack using the step histtype
+#
+
+P.figure()
+
+n, bins, patches = P.hist(x, 10, histtype='step', stacked=True, fill=True)
+
+P.show()
#
# finally: make a multiple-histogram of data-sets with different length
View
37 lib/matplotlib/axes.py
@@ -7728,7 +7728,7 @@ def get_shared_y_axes(self):
def hist(self, x, bins=10, range=None, normed=False, weights=None,
cumulative=False, bottom=None, histtype='bar', align='mid',
orientation='vertical', rwidth=None, log=False,
- color=None, label=None,
+ color=None, label=None, stacked=False,
**kwargs):
"""
Plot a histogram.
@@ -7738,7 +7738,7 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
hist(x, bins=10, range=None, normed=False, weights=None,
cumulative=False, bottom=None, histtype='bar', align='mid',
orientation='vertical', rwidth=None, log=False,
- color=None, label=None,
+ color=None, label=None, stacked=False,
**kwargs)
Compute and draw the histogram of *x*. The return value is a
@@ -7862,6 +7862,11 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
ax.hist(12+3*np.random.randn(1000), label='women', alpha=0.5)
ax.legend()
+ *stacked*:
+ If *True*, multiple data are stacked on top of each other
+ If *False* multiple data are aranged side by side if
+ histtype is 'bar' or on top of each other if histtype is 'step'
+
.
kwargs are used to update the properties of the
@@ -7901,6 +7906,9 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
'hist now uses the rwidth to give relative width '
'and not absolute width')
+ if histtype == 'barstacked' and not stacked:
+ stacked=True
+
# Massage 'x' for processing.
# NOTE: Be sure any changes here is also done below to 'weights'
if isinstance(x, np.ndarray) or not iterable(x[0]):
@@ -7986,13 +7994,21 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
hist_kwargs['new'] = True
n = []
- for i in xrange(nx):
+ mlast = bottom
+ # reversed order is necessary so when stacking histogram, first dataset is on top
+ # if histogram isn't stacked, this doesn't make any difference
+ for i in reversed(xrange(nx)):
# this will automatically overwrite bins,
# so that each histogram uses the same bins
m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
+ if mlast is None:
+ mlast = np.zeros(len(bins)-1, np.int)
@WeatherGod Collaborator

Just a thought... are we guaranteed that bins will have a non-zero length? If not, then it would be a good idea to catch the length-zero case and raise a descriptive exception.

@neggert
neggert added a note

The bins argument to np.histogram takes either the number of bins or an array of bin edges.

I just played around a little, and I don't think it's possible for np.histogram to return a zero-length array of bin edges. It raises an exception if one tries to set bins=0

In fact, the only way I can get it to return anything less than a length-2 array is by explicitly passing only one bin edge. This will obviously result in some strange behavior, but that's a pretty edge case. If np.histogram doesn't raise an exception for that, I don't think we should, either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
if normed:
db = np.diff(bins)
m = (m.astype(float) / db) / m.sum()
+ if stacked:
+ m += mlast
+ mlast[:] = m
n.append(m)
if cumulative:
@@ -8005,6 +8021,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
else:
n = [m[slc].cumsum()[slc] for m in n]
+ n.reverse() # put them back in the right order
+
patches = []
if histtype.startswith('bar'):
@@ -8017,7 +8035,7 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
else:
dr = 1.0
- if histtype=='bar':
+ if histtype=='bar' and not stacked:
width = dr*totwidth/nx
dw = width
@@ -8026,10 +8044,9 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
else:
boffset = 0.0
stacked = False
- elif histtype=='barstacked':
+ elif histtype=='barstacked' or stacked:
width = dr*totwidth
boffset, dw = 0.0, 0.0
- stacked = True
if align == 'mid' or align == 'edge':
boffset += 0.5*totwidth
@@ -8042,14 +8059,10 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
_barfunc = self.bar
for m, c in zip(n, color):
- patch = _barfunc(bins[:-1]+boffset, m, width, bottom,
+ patch = _barfunc(bins[:-1]+boffset, m, width,
align='center', log=log,
color=c)
patches.append(patch)
- if stacked:
- if bottom is None:
- bottom = 0.0
- bottom += m
boffset += dw
elif histtype.startswith('step'):
@@ -8072,6 +8085,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
else: # orientation == 'vertical'
self.set_yscale('log')
+ # If fill kwarg is set, it will be passed to the patch collection,
+ # overriding this
fill = (histtype == 'stepfilled')
for m, c in zip(n, color):
View
3  lib/matplotlib/pyplot.py
@@ -2642,7 +2642,8 @@ def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear',
@_autogen_docstring(Axes.hist)
def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False,
bottom=None, histtype='bar', align='mid', orientation='vertical',
- rwidth=None, log=False, color=None, label=None, hold=None, **kwargs):
+ rwidth=None, log=False, color=None, label=None, stacked=False,
+ hold=None, **kwargs):
ax = gca()
# allow callers to override the hold state by passing hold=True|False
washold = ax.ishold()
View
BIN  lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.pdf
Binary file not shown
View
BIN  lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
558 lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.svg
@@ -0,0 +1,558 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Created with matplotlib (http://matplotlib.sourceforge.net/) -->
+<svg height="432pt" version="1.1" viewBox="0 0 576 432" width="576pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <style type="text/css">
+*{stroke-linecap:square;stroke-linejoin:round;}
+ </style>
+ </defs>
+ <g id="figure_1">
+ <g id="patch_1">
+ <path d="
+M0 432
+L576 432
+L576 0
+L0 0
+z
+" style="fill:#ffffff;"/>
+ </g>
+ <g id="axes_1">
+ <g id="patch_2">
+ <path d="
+M72 388.8
+L518.4 388.8
+L518.4 43.2
+L72 43.2
+z
+" style="fill:#ffffff;"/>
+ </g>
+ <g id="patch_3">
+ <path clip-path="url(#p7ff5b81e1d)" d="
+M72 388.8
+L72 280.8
+L116.64 280.8
+L116.64 64.8
+L161.28 64.8
+L161.28 86.4
+L205.92 86.4
+L205.92 259.2
+L250.56 259.2
+L250.56 280.8
+L295.2 280.8
+L295.2 280.8
+L339.84 280.8
+L339.84 280.8
+L384.48 280.8
+L384.48 280.8
+L429.12 280.8
+L429.12 280.8
+L473.76 280.8
+L473.76 280.8
+L518.4 280.8
+L518.4 388.8" style="fill:#0000ff;stroke:#000000;"/>
+ </g>
+ <g id="patch_4">
+ <path clip-path="url(#p7ff5b81e1d)" d="
+M72 388.8
+L72 388.8
+L116.64 388.8
+L116.64 172.8
+L161.28 172.8
+L161.28 194.4
+L205.92 194.4
+L205.92 367.2
+L250.56 367.2
+L250.56 388.8
+L295.2 388.8
+L295.2 388.8
+L339.84 388.8
+L339.84 388.8
+L384.48 388.8
+L384.48 388.8
+L429.12 388.8
+L429.12 388.8
+L473.76 388.8
+L473.76 388.8
+L518.4 388.8
+L518.4 388.8" style="fill:#008000;stroke:#000000;"/>
+ </g>
+ <g id="matplotlib.axis_1">
+ <g id="xtick_1">
+ <g id="line2d_1">
+ <defs>
+ <path d="
+M0 0
+L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_2">
+ <defs>
+ <path d="
+M0 0
+L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_1">
+ <!-- 0 -->
+ <defs>
+ <path d="
+M31.7812 66.4062
+Q24.1719 66.4062 20.3281 58.9062
+Q16.5 51.4219 16.5 36.375
+Q16.5 21.3906 20.3281 13.8906
+Q24.1719 6.39062 31.7812 6.39062
+Q39.4531 6.39062 43.2812 13.8906
+Q47.125 21.3906 47.125 36.375
+Q47.125 51.4219 43.2812 58.9062
+Q39.4531 66.4062 31.7812 66.4062
+M31.7812 74.2188
+Q44.0469 74.2188 50.5156 64.5156
+Q56.9844 54.8281 56.9844 36.375
+Q56.9844 17.9688 50.5156 8.26562
+Q44.0469 -1.42188 31.7812 -1.42188
+Q19.5312 -1.42188 13.0625 8.26562
+Q6.59375 17.9688 6.59375 36.375
+Q6.59375 54.8281 13.0625 64.5156
+Q19.5312 74.2188 31.7812 74.2188" id="BitstreamVeraSans-Roman-30"/>
+ </defs>
+ <g transform="translate(68.9765625 401.70625)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-30"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_2">
+ <g id="line2d_3">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="161.28" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_4">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="161.28" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_2">
+ <!-- 2 -->
+ <defs>
+ <path d="
+M19.1875 8.29688
+L53.6094 8.29688
+L53.6094 0
+L7.32812 0
+L7.32812 8.29688
+Q12.9375 14.1094 22.625 23.8906
+Q32.3281 33.6875 34.8125 36.5312
+Q39.5469 41.8438 41.4219 45.5312
+Q43.3125 49.2188 43.3125 52.7812
+Q43.3125 58.5938 39.2344 62.25
+Q35.1562 65.9219 28.6094 65.9219
+Q23.9688 65.9219 18.8125 64.3125
+Q13.6719 62.7031 7.8125 59.4219
+L7.8125 69.3906
+Q13.7656 71.7812 18.9375 73
+Q24.125 74.2188 28.4219 74.2188
+Q39.75 74.2188 46.4844 68.5469
+Q53.2188 62.8906 53.2188 53.4219
+Q53.2188 48.9219 51.5312 44.8906
+Q49.8594 40.875 45.4062 35.4062
+Q44.1875 33.9844 37.6406 27.2188
+Q31.1094 20.4531 19.1875 8.29688" id="BitstreamVeraSans-Roman-32"/>
+ </defs>
+ <g transform="translate(158.503125 401.70625)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-32"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_3">
+ <g id="line2d_5">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="250.56" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_6">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="250.56" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_3">
+ <!-- 4 -->
+ <defs>
+ <path d="
+M37.7969 64.3125
+L12.8906 25.3906
+L37.7969 25.3906
+z
+
+M35.2031 72.9062
+L47.6094 72.9062
+L47.6094 25.3906
+L58.0156 25.3906
+L58.0156 17.1875
+L47.6094 17.1875
+L47.6094 0
+L37.7969 0
+L37.7969 17.1875
+L4.89062 17.1875
+L4.89062 26.7031
+z
+" id="BitstreamVeraSans-Roman-34"/>
+ </defs>
+ <g transform="translate(247.3725 401.54875)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-34"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_4">
+ <g id="line2d_7">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="339.84" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_8">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="339.84" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_4">
+ <!-- 6 -->
+ <defs>
+ <path d="
+M33.0156 40.375
+Q26.375 40.375 22.4844 35.8281
+Q18.6094 31.2969 18.6094 23.3906
+Q18.6094 15.5312 22.4844 10.9531
+Q26.375 6.39062 33.0156 6.39062
+Q39.6562 6.39062 43.5312 10.9531
+Q47.4062 15.5312 47.4062 23.3906
+Q47.4062 31.2969 43.5312 35.8281
+Q39.6562 40.375 33.0156 40.375
+M52.5938 71.2969
+L52.5938 62.3125
+Q48.875 64.0625 45.0938 64.9844
+Q41.3125 65.9219 37.5938 65.9219
+Q27.8281 65.9219 22.6719 59.3281
+Q17.5312 52.7344 16.7969 39.4062
+Q19.6719 43.6562 24.0156 45.9219
+Q28.375 48.1875 33.5938 48.1875
+Q44.5781 48.1875 50.9531 41.5156
+Q57.3281 34.8594 57.3281 23.3906
+Q57.3281 12.1562 50.6875 5.35938
+Q44.0469 -1.42188 33.0156 -1.42188
+Q20.3594 -1.42188 13.6719 8.26562
+Q6.98438 17.9688 6.98438 36.375
+Q6.98438 53.6562 15.1875 63.9375
+Q23.3906 74.2188 37.2031 74.2188
+Q40.9219 74.2188 44.7031 73.4844
+Q48.4844 72.75 52.5938 71.2969" id="BitstreamVeraSans-Roman-36"/>
+ </defs>
+ <g transform="translate(336.819375 401.70625)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-36"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_5">
+ <g id="line2d_9">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="429.12" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_10">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="429.12" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_5">
+ <!-- 8 -->
+ <defs>
+ <path d="
+M31.7812 34.625
+Q24.75 34.625 20.7188 30.8594
+Q16.7031 27.0938 16.7031 20.5156
+Q16.7031 13.9219 20.7188 10.1562
+Q24.75 6.39062 31.7812 6.39062
+Q38.8125 6.39062 42.8594 10.1719
+Q46.9219 13.9688 46.9219 20.5156
+Q46.9219 27.0938 42.8906 30.8594
+Q38.875 34.625 31.7812 34.625
+M21.9219 38.8125
+Q15.5781 40.375 12.0312 44.7188
+Q8.5 49.0781 8.5 55.3281
+Q8.5 64.0625 14.7188 69.1406
+Q20.9531 74.2188 31.7812 74.2188
+Q42.6719 74.2188 48.875 69.1406
+Q55.0781 64.0625 55.0781 55.3281
+Q55.0781 49.0781 51.5312 44.7188
+Q48 40.375 41.7031 38.8125
+Q48.8281 37.1562 52.7969 32.3125
+Q56.7812 27.4844 56.7812 20.5156
+Q56.7812 9.90625 50.3125 4.23438
+Q43.8438 -1.42188 31.7812 -1.42188
+Q19.7344 -1.42188 13.25 4.23438
+Q6.78125 9.90625 6.78125 20.5156
+Q6.78125 27.4844 10.7812 32.3125
+Q14.7969 37.1562 21.9219 38.8125
+M18.3125 54.3906
+Q18.3125 48.7344 21.8438 45.5625
+Q25.3906 42.3906 31.7812 42.3906
+Q38.1406 42.3906 41.7188 45.5625
+Q45.3125 48.7344 45.3125 54.3906
+Q45.3125 60.0625 41.7188 63.2344
+Q38.1406 66.4062 31.7812 66.4062
+Q25.3906 66.4062 21.8438 63.2344
+Q18.3125 60.0625 18.3125 54.3906" id="BitstreamVeraSans-Roman-38"/>
+ </defs>
+ <g transform="translate(426.12 401.70625)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-38"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_6">
+ <g id="line2d_11">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_12">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_6">
+ <!-- 10 -->
+ <defs>
+ <path d="
+M12.4062 8.29688
+L28.5156 8.29688
+L28.5156 63.9219
+L10.9844 60.4062
+L10.9844 69.3906
+L28.4219 72.9062
+L38.2812 72.9062
+L38.2812 8.29688
+L54.3906 8.29688
+L54.3906 0
+L12.4062 0
+z
+" id="BitstreamVeraSans-Roman-31"/>
+ </defs>
+ <g transform="translate(511.8225 401.70625)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-31"/>
+ <use x="63.623046875" xlink:href="#BitstreamVeraSans-Roman-30"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g id="matplotlib.axis_2">
+ <g id="ytick_1">
+ <g id="line2d_13">
+ <defs>
+ <path d="
+M0 0
+L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_14">
+ <defs>
+ <path d="
+M0 0
+L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="388.8"/>
+ </g>
+ </g>
+ <g id="text_7">
+ <!-- 0 -->
+ <g transform="translate(61.953125 393.1678125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-30"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_2">
+ <g id="line2d_15">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="345.6"/>
+ </g>
+ </g>
+ <g id="line2d_16">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="345.6"/>
+ </g>
+ </g>
+ <g id="text_8">
+ <!-- 2 -->
+ <g transform="translate(62.44625 350.053125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-32"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_3">
+ <g id="line2d_17">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="302.4"/>
+ </g>
+ </g>
+ <g id="line2d_18">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="302.4"/>
+ </g>
+ </g>
+ <g id="text_9">
+ <!-- 4 -->
+ <g transform="translate(61.625 306.774375)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-34"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_4">
+ <g id="line2d_19">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="259.2"/>
+ </g>
+ </g>
+ <g id="line2d_20">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="259.2"/>
+ </g>
+ </g>
+ <g id="text_10">
+ <!-- 6 -->
+ <g transform="translate(61.95875 263.5678125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-36"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_5">
+ <g id="line2d_21">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="216.0"/>
+ </g>
+ </g>
+ <g id="line2d_22">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="216.0"/>
+ </g>
+ </g>
+ <g id="text_11">
+ <!-- 8 -->
+ <g transform="translate(62.0 220.3678125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-38"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_6">
+ <g id="line2d_23">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="172.8"/>
+ </g>
+ </g>
+ <g id="line2d_24">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="172.8"/>
+ </g>
+ </g>
+ <g id="text_12">
+ <!-- 10 -->
+ <g transform="translate(54.845 177.1678125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-31"/>
+ <use x="63.623046875" xlink:href="#BitstreamVeraSans-Roman-30"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_7">
+ <g id="line2d_25">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="129.6"/>
+ </g>
+ </g>
+ <g id="line2d_26">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="129.6"/>
+ </g>
+ </g>
+ <g id="text_13">
+ <!-- 12 -->
+ <g transform="translate(55.25 134.053125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-31"/>
+ <use x="63.623046875" xlink:href="#BitstreamVeraSans-Roman-32"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_8">
+ <g id="line2d_27">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="86.4"/>
+ </g>
+ </g>
+ <g id="line2d_28">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="86.4"/>
+ </g>
+ </g>
+ <g id="text_14">
+ <!-- 14 -->
+ <g transform="translate(54.72125 90.774375)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-31"/>
+ <use x="63.623046875" xlink:href="#BitstreamVeraSans-Roman-34"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_9">
+ <g id="line2d_29">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="43.2"/>
+ </g>
+ </g>
+ <g id="line2d_30">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="43.2"/>
+ </g>
+ </g>
+ <g id="text_15">
+ <!-- 16 -->
+ <g transform="translate(54.80375 47.5678125)scale(0.12 -0.12)">
+ <use xlink:href="#BitstreamVeraSans-Roman-31"/>
+ <use x="63.623046875" xlink:href="#BitstreamVeraSans-Roman-36"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g id="patch_5">
+ <path d="
+M72 43.2
+L518.4 43.2" style="fill:none;stroke:#000000;"/>
+ </g>
+ <g id="patch_6">
+ <path d="
+M518.4 388.8
+L518.4 43.2" style="fill:none;stroke:#000000;"/>
+ </g>
+ <g id="patch_7">
+ <path d="
+M72 388.8
+L518.4 388.8" style="fill:none;stroke:#000000;"/>
+ </g>
+ <g id="patch_8">
+ <path d="
+M72 388.8
+L72 43.2" style="fill:none;stroke:#000000;"/>
+ </g>
+ </g>
+ </g>
+ <defs>
+ <clipPath id="p7ff5b81e1d">
+ <rect height="345.6" width="446.4" x="72.0" y="43.2"/>
+ </clipPath>
+ </defs>
+</svg>
View
9 lib/matplotlib/tests/test_axes.py
@@ -856,6 +856,15 @@ def test_errorbar():
fig.suptitle('Variable errorbars')
+@image_comparison(baseline_images=['hist_stacked'])
+def test_hist_stacked():
+ # make some data
+ d1 = np.linspace(0, 10, 50)
+ d2 = np.linspace(1, 3, 20)
+ fig = plt.figure()
+ ax = fig.add_subplot(111)
+ ax.hist( (d1, d2), histtype="stepfilled", stacked=True)
+
if __name__=='__main__':
import nose
nose.runmodule(argv=['-s','--with-doctest'], exit=False)
Something went wrong with that request. Please try again.