chiark / gitweb /
m.plots: support stacked values.
authorVladimír Vondruš <mosra@centrum.cz>
Sun, 7 Jul 2019 11:18:17 +0000 (13:18 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Sun, 7 Jul 2019 12:10:41 +0000 (14:10 +0200)
doc/plugins/plots-and-graphs.rst
documentation/test_python/page_plugins/index.html
plugins/m/plots.py
plugins/m/test/plots/page.html
plugins/m/test/plots/page.rst

index 4d3aa6ca6f5ff75cd344fa6cbd0b715cf3759c9e..2e6101c3b2f236a853de710fc8ffe261dde6b7b8 100644 (file)
@@ -129,7 +129,8 @@ height is calculated automatically based on amount of values, you can adjust
 the bar height using :rst:`:bar_height:`. Default value is :py:`0.4`.
 
 It's possible to add an extra line of labels using :rst:`:labels_extra:`.
-Again, there should be as many entries as primary labels and values. To omit an extra label for a value, specify it as the :abbr:`reST <reStructuredText>`
+Again, there should be as many entries as primary labels and values. To omit an
+extra label for a value, specify it as the :abbr:`reST <reStructuredText>`
 comment :rst:`..`.
 
 .. code-figure::
@@ -172,6 +173,64 @@ comment :rst:`..`.
         :colors: success info danger dim
         :bar_height: 0.6
 
+`Stacked values`_
+-----------------
+
+It's possible to stack several values on each other by providing a second
+(third, ...) like for :rst:`:values:` (and :rst:`:errors:` as well). The values
+are added together --- not overlapped --- so e.g. showing values of 20 and 40
+stacked together will result in the bar being 60 units long in total. Hovering
+over the stacked values will show magnitude of just given part, not the summed
+value.
+
+The :rst:`:colors:` option works for these as well, either have each line a
+single value on each line to color each "slice" differently, or have one color
+per value like shown above.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. plot:: Download size (*.js, *.wasm)
+            :type: barh
+            :labels:
+                Sdl2Application
+                Sdl2Application
+                EmscriptenApplication
+            :labels_extra:
+                -s USE_SDL=2
+                -s USE_SDL=1
+                ..
+            :units: kB
+            :values:
+                111.9 74.4 52.1
+                731.2 226.3 226.0
+            :colors:
+                success
+                info
+
+    .. plot:: Download size (*.js, *.wasm)
+        :type: barh
+        :labels:
+            Sdl2Application
+            Sdl2Application
+            EmscriptenApplication
+        :labels_extra:
+            -s USE_SDL=2
+            -s USE_SDL=1
+            ..
+        :units: kB
+        :values:
+            111.9 74.4 52.1
+            731.2 226.3 226.0
+        :colors:
+            success
+            info
+
+    .. class:: m-text-center m-text m-dim m-small
+
+    (graph source: https://blog.magnum.graphics/announcements/new-emscripten-application-implementation/)
+
 `Graphs`_
 =========
 
index 8368a6efaee5497b0b02500fefed62553fa1dca2..03673af73fb039f46c5091fdb29b5520f5ff05d9 100644 (file)
@@ -67,10 +67,10 @@ div.m-plot svg { font-family: DejaVu Sans; }
    <g id="patch_1">
     <path d="M 59.365156 69.588125 L 560.62 69.588125 L 560.62 27.757969 L 59.365156 27.757969 z" class="m-background"/>
    </g>
-   <g id="plot1-value0"><title>15.0 meters, i guess?</title>
+   <g id="plot1-value0-0"><title>15.0 meters, i guess?</title>
     <path clip-path="url(#p2abd2612b1)" d="M 59.365156 29.659339 L 298.057939 29.659339 L 298.057939 46.560413 L 59.365156 46.560413 z" class="m-bar m-success"/>
    </g>
-   <g id="plot1-value1"><title>30.0 meters, i guess?</title>
+   <g id="plot1-value0-1"><title>30.0 meters, i guess?</title>
     <path clip-path="url(#p2abd2612b1)" d="M 59.365156 50.785681 L 536.750722 50.785681 L 536.750722 67.686754 L 59.365156 67.686754 z" class="m-bar m-success"/>
    </g>
    <g id="matplotlib.axis_1">
index 9c84fd71826977a7f8365f8c7315c446f45e68cb..94e0b35d43a0db5a87fd14b3ce3b32dcbf3227de 100644 (file)
@@ -126,9 +126,9 @@ _class_mapping = [
 ]
 
 # Titles for bars
-_bar_titles_src = '<g id="plot{}-value{}">'
-_bar_titles_dst = '<g id="plot{}-value{}"><title>{} {}</title>'
-_bar_titles_dst_error = '<g id="plot{}-value{}"><title>{} ± {} {}</title>'
+_bar_titles_src = '<g id="plot{}-value{}-{}">'
+_bar_titles_dst = '<g id="plot{}-value{}-{}"><title>{} {}</title>'
+_bar_titles_dst_error = '<g id="plot{}-value{}-{}"><title>{} ± {} {}</title>'
 
 class Plot(rst.Directive):
     required_arguments = 1
@@ -164,20 +164,36 @@ class Plot(rst.Directive):
         else:
             labels_extra = None
 
-        # Values. Should be one for each label.
-        values = [float(v) for v in self.options['values'].split()]
-        assert len(values) == len(labels)
+        # Values. Should be one for each label, if there are multiple lines
+        # then the values get stacked.
+        value_sets = []
+        for row in self.options['values'].split('\n'):
+            values = [float(v) for v in row.split()]
+            assert len(values) == len(labels)
+            value_sets += [values]
 
         # Optional errors
         if 'errors' in self.options:
-            errors = [float(e) for e in self.options['errors'].split()]
+            error_sets = []
+            for row in self.options['errors'].split('\n'):
+                errors = [float(e) for e in row.split()]
+                assert len(errors) == len(values)
+                error_sets += [errors]
+            assert len(error_sets) == len(value_sets)
         else:
-            errors = None
+            error_sets = [None]*len(value_sets)
 
         # Colors. Should be either one for all or one for every value
-        colors = [style_mapping[c] for c in self.options.get('colors', 'default').split()]
-        if len(colors) == 1: colors = colors[0]
-        else: assert len(colors) == len(labels)
+        if 'colors' in self.options:
+            color_sets = []
+            for row in self.options['colors'].split('\n'):
+                colors = [style_mapping[c] for c in row.split()]
+                if len(colors) == 1: colors = colors[0]
+                else: assert len(colors) == len(labels)
+                color_sets += [colors]
+            assert len(color_sets) == len(value_sets)
+        else:
+            color_sets = [style_mapping['default']]*len(value_sets)
 
         # Bar height
         bar_height = float(self.options.get('bar_height', '0.4'))
@@ -188,12 +204,15 @@ class Plot(rst.Directive):
         # Setup the graph
         fig, ax = plt.subplots()
         # TODO: let matplotlib calculate the height somehow
-        fig.set_size_inches(8, 0.78 + len(values)*bar_height)
+        fig.set_size_inches(8, 0.78 + len(labels)*bar_height)
         yticks = np.arange(len(labels))
-        plot = ax.barh(yticks, values, xerr=errors,
-                       align='center', color=colors, ecolor='#cafe0a', capsize=5*bar_height/0.4)
-        for i, v in enumerate(plot):
-            v.set_gid('plot{}-value{}'.format(mpl.rcParams['svg.hashsalt'], i))
+        left = np.array([0.0]*len(labels))
+        for i in range(len(value_sets)):
+            plot = ax.barh(yticks, value_sets[i], xerr=error_sets[i],
+                           align='center', color=color_sets[i], ecolor='#cafe0a', capsize=5*bar_height/0.4, left=left)
+            left += np.array(value_sets[i])
+            for j, v in enumerate(plot):
+                v.set_gid('plot{}-value{}-{}'.format(mpl.rcParams['svg.hashsalt'], i, j))
         ax.set_yticks(yticks)
         ax.invert_yaxis() # top-to-bottom
         ax.set_xlabel(units)
@@ -224,13 +243,15 @@ class Plot(rst.Directive):
         # Replace color codes with CSS classes
         for src, dst in _class_mapping: imgdata = imgdata.replace(src, dst)
         # Add titles for bars
-        for i in range(len(values)):
-            if errors: imgdata = imgdata.replace(
-                _bar_titles_src.format(mpl.rcParams['svg.hashsalt'], i),
-                _bar_titles_dst_error.format(mpl.rcParams['svg.hashsalt'], i, values[i], errors[i], units))
-            else: imgdata = imgdata.replace(
-                _bar_titles_src.format(mpl.rcParams['svg.hashsalt'], i),
-                _bar_titles_dst.format(mpl.rcParams['svg.hashsalt'], i, values[i], units))
+        for i in range(len(value_sets)):
+            for j in range(len(labels)):
+                id = i*len(labels) + j
+                if error_sets[i]: imgdata = imgdata.replace(
+                    _bar_titles_src.format(mpl.rcParams['svg.hashsalt'], i, j),
+                    _bar_titles_dst_error.format(mpl.rcParams['svg.hashsalt'], i, j, value_sets[i][j], error_sets[i][j], units))
+                else: imgdata = imgdata.replace(
+                    _bar_titles_src.format(mpl.rcParams['svg.hashsalt'], i, j),
+                    _bar_titles_dst.format(mpl.rcParams['svg.hashsalt'], i, j, value_sets[i][j], units))
 
         container = nodes.container(**self.options)
         container['classes'] += ['m-plot']
index 896edd1f0ba81cb3726dc27a8be47953827b9d78..e6598208de4feb2e2f1a29ac31bae3a9334f4981 100644 (file)
@@ -39,10 +39,10 @@ div.m-plot svg { font-family: DejaVu Sans; }
    <g id="patch_1">
     <path d="M 59.365156 69.588125 L 560.62 69.588125 L 560.62 27.757969 L 59.365156 27.757969 z" class="m-background"/>
    </g>
-   <g id="plot1-value0"><title>15.0 meters, i guess?</title>
+   <g id="plot1-value0-0"><title>15.0 meters, i guess?</title>
     <path clip-path="url(#p2abd2612b1)" d="M 59.365156 29.659339 L 298.057939 29.659339 L 298.057939 46.560413 L 59.365156 46.560413 z" class="m-bar m-success"/>
    </g>
-   <g id="plot1-value1"><title>30.0 meters, i guess?</title>
+   <g id="plot1-value0-1"><title>30.0 meters, i guess?</title>
     <path clip-path="url(#p2abd2612b1)" d="M 59.365156 50.785681 L 536.750722 50.785681 L 536.750722 67.686754 L 59.365156 67.686754 z" class="m-bar m-success"/>
    </g>
    <g id="matplotlib.axis_1">
@@ -172,13 +172,13 @@ div.m-plot svg { font-family: DejaVu Sans; }
    <g id="patch_1">
     <path d="M 68.216719 173.988125 L 558.482422 173.988125 L 558.482422 27.757969 L 68.216719 27.757969 z" class="m-background"/>
    </g>
-   <g id="plot2-value0"><title>3.0 ± 0.1 Mondays</title>
+   <g id="plot2-value0-0"><title>3.0 ± 0.1 Mondays</title>
     <path clip-path="url(#p1198f4ed7e)" d="M 68.216719 34.404794 L 297.849367 34.404794 L 297.849367 72.386653 L 68.216719 72.386653 z" class="m-bar m-success"/>
    </g>
-   <g id="plot2-value1"><title>4.0 ± 2.1 Mondays</title>
+   <g id="plot2-value0-1"><title>4.0 ± 2.1 Mondays</title>
     <path clip-path="url(#p1198f4ed7e)" d="M 68.216719 81.882117 L 374.393583 81.882117 L 374.393583 119.863976 L 68.216719 119.863976 z" class="m-bar m-info"/>
    </g>
-   <g id="plot2-value2"><title>5.0 ± 1.0 Mondays</title>
+   <g id="plot2-value0-2"><title>5.0 ± 1.0 Mondays</title>
     <path clip-path="url(#p1198f4ed7e)" d="M 68.216719 129.359441 L 450.937798 129.359441 L 450.937798 167.3413 L 68.216719 167.3413 z" class="m-bar m-danger"/>
    </g>
    <g id="matplotlib.axis_1">
@@ -338,6 +338,345 @@ div.m-plot svg { font-family: DejaVu Sans; }
  </defs>
 </svg>
 </div>
+<div class="m-plot">
+<svg viewBox="0 0 576 142.56">
+ <defs>
+  <style type="text/css">
+*{stroke-linecap:butt;stroke-linejoin:round;}
+  </style>
+ </defs>
+ <g id="figure_1">
+  <g id="axes_1">
+   <g id="patch_1">
+    <path d="M 26.561094 98.388125 L 560.62 98.388125 L 560.62 27.757969 L 26.561094 27.757969 z" class="m-background"/>
+   </g>
+   <g id="plot3-value0-0"><title>111.9 kB</title>
+    <path clip-path="url(#pd6a36f6853)" d="M 26.561094 30.96843 L 94.068413 30.96843 L 94.068413 49.313926 L 26.561094 49.313926 z" class="m-bar m-success"/>
+   </g>
+   <g id="plot3-value0-1"><title>74.4 kB</title>
+    <path clip-path="url(#pd6a36f6853)" d="M 26.561094 53.900299 L 71.445317 53.900299 L 71.445317 72.245794 L 26.561094 72.245794 z" class="m-bar m-success"/>
+   </g>
+   <g id="plot3-value0-2"><title>52.1 kB</title>
+    <path clip-path="url(#pd6a36f6853)" d="M 26.561094 76.832168 L 57.992115 76.832168 L 57.992115 95.177663 L 26.561094 95.177663 z" class="m-bar m-success"/>
+   </g>
+   <g id="plot3-value1-0"><title>731.2 kB</title>
+    <path clip-path="url(#pd6a36f6853)" d="M 94.068413 30.96843 L 535.188624 30.96843 L 535.188624 49.313926 L 94.068413 49.313926 z" class="m-bar m-info"/>
+   </g>
+   <g id="plot3-value1-1"><title>226.3 kB</title>
+    <path clip-path="url(#pd6a36f6853)" d="M 71.445317 53.900299 L 207.968161 53.900299 L 207.968161 72.245794 L 71.445317 72.245794 z" class="m-bar m-info"/>
+   </g>
+   <g id="plot3-value1-2"><title>226.0 kB</title>
+    <path clip-path="url(#pd6a36f6853)" d="M 57.992115 76.832168 L 194.333975 76.832168 L 194.333975 95.177663 L 57.992115 95.177663 z" class="m-bar m-info"/>
+   </g>
+   <g id="matplotlib.axis_1">
+    <g id="xtick_1">
+     <g id="line2d_1">
+      <defs>
+       <path d="M 0 0 L 0 3.5" id="m230bf1d664" class="m-line"/>
+      </defs>
+      <g>
+       <use x="26.561094" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_1">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 26.561094, 113.746406)" x="26.561094" y="113.746406">0</text>
+     </g>
+    </g>
+    <g id="xtick_2">
+     <g id="line2d_2">
+      <g>
+       <use x="86.88935" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_2">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 86.88935, 113.746406)" x="86.88935" y="113.746406">100</text>
+     </g>
+    </g>
+    <g id="xtick_3">
+     <g id="line2d_3">
+      <g>
+       <use x="147.217607" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_3">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 147.217607, 113.746406)" x="147.217607" y="113.746406">200</text>
+     </g>
+    </g>
+    <g id="xtick_4">
+     <g id="line2d_4">
+      <g>
+       <use x="207.545863" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_4">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 207.545863, 113.746406)" x="207.545863" y="113.746406">300</text>
+     </g>
+    </g>
+    <g id="xtick_5">
+     <g id="line2d_5">
+      <g>
+       <use x="267.874119" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_5">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 267.874119, 113.746406)" x="267.874119" y="113.746406">400</text>
+     </g>
+    </g>
+    <g id="xtick_6">
+     <g id="line2d_6">
+      <g>
+       <use x="328.202376" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_6">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 328.202376, 113.746406)" x="328.202376" y="113.746406">500</text>
+     </g>
+    </g>
+    <g id="xtick_7">
+     <g id="line2d_7">
+      <g>
+       <use x="388.530632" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_7">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 388.530632, 113.746406)" x="388.530632" y="113.746406">600</text>
+     </g>
+    </g>
+    <g id="xtick_8">
+     <g id="line2d_8">
+      <g>
+       <use x="448.858889" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_8">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 448.858889, 113.746406)" x="448.858889" y="113.746406">700</text>
+     </g>
+    </g>
+    <g id="xtick_9">
+     <g id="line2d_9">
+      <g>
+       <use x="509.187145" xlink:href="#m230bf1d664" y="98.388125"/>
+      </g>
+     </g>
+     <g id="text_9">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 509.187145, 113.746406)" x="509.187145" y="113.746406">800</text>
+     </g>
+    </g>
+    <g id="text_10">
+     <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 293.590547, 128.392344)" x="293.590547" y="128.392344">kB</text>
+    </g>
+   </g>
+   <g id="matplotlib.axis_2">
+    <g id="ytick_1">
+     <g id="line2d_10">
+      <defs>
+       <path d="M 0 0 L -3.5 0" id="m1924854559" class="m-line"/>
+      </defs>
+      <g>
+       <use x="26.561094" xlink:href="#m1924854559" y="40.141178"/>
+      </g>
+     </g>
+     <g id="text_11">
+      <text class="m-label" style="text-anchor:end;" transform="rotate(-0, 19.561094, 44.320319)" x="19.561094" y="44.320319">A</text>
+     </g>
+    </g>
+    <g id="ytick_2">
+     <g id="line2d_11">
+      <g>
+       <use x="26.561094" xlink:href="#m1924854559" y="63.073047"/>
+      </g>
+     </g>
+     <g id="text_12">
+      <text class="m-label" style="text-anchor:end;" transform="rotate(-0, 19.561094, 67.252188)" x="19.561094" y="67.252188">B</text>
+     </g>
+    </g>
+    <g id="ytick_3">
+     <g id="line2d_12">
+      <g>
+       <use x="26.561094" xlink:href="#m1924854559" y="86.004916"/>
+      </g>
+     </g>
+     <g id="text_13">
+      <text class="m-label" style="text-anchor:end;" transform="rotate(-0, 19.561094, 90.184056)" x="19.561094" y="90.184056">C</text>
+     </g>
+    </g>
+   </g>
+   <g id="text_14">
+    <text class="m-title" style="text-anchor:middle;" transform="rotate(-0, 293.590547, 21.757969)" x="293.590547" y="21.757969">Stacked plot</text>
+   </g>
+  </g>
+ </g>
+ <defs>
+  <clipPath id="pd6a36f6853">
+   <rect height="70.630156" width="534.058906" x="26.561094" y="27.757969"/>
+  </clipPath>
+ </defs>
+</svg>
+</div>
+<div class="m-plot">
+<svg viewBox="0 0 576 113.76">
+ <defs>
+  <style type="text/css">
+*{stroke-linecap:butt;stroke-linejoin:round;}
+  </style>
+ </defs>
+ <g id="figure_1">
+  <g id="axes_1">
+   <g id="patch_1">
+    <path d="M 26.427031 69.588125 L 560.62 69.588125 L 560.62 27.757969 L 26.427031 27.757969 z" class="m-background"/>
+   </g>
+   <g id="plot4-value0-0"><title>111.9 ± 25.0 kB</title>
+    <path clip-path="url(#pf9f5e4e753)" d="M 26.427031 29.659339 L 81.004452 29.659339 L 81.004452 46.560413 L 26.427031 46.560413 z" class="m-bar m-success"/>
+   </g>
+   <g id="plot4-value0-1"><title>74.4 ± 15.3 kB</title>
+    <path clip-path="url(#pf9f5e4e753)" d="M 26.427031 50.785681 L 62.714432 50.785681 L 62.714432 67.686754 L 26.427031 67.686754 z" class="m-bar m-danger"/>
+   </g>
+   <g id="plot4-value1-0"><title>731.2 ± 200.0 kB</title>
+    <path clip-path="url(#pf9f5e4e753)" d="M 81.004452 29.659339 L 437.635464 29.659339 L 437.635464 46.560413 L 81.004452 46.560413 z" class="m-bar m-info"/>
+   </g>
+   <g id="plot4-value1-1"><title>226.3 ± 5.0 kB</title>
+    <path clip-path="url(#pf9f5e4e753)" d="M 62.714432 50.785681 L 173.088608 50.785681 L 173.088608 67.686754 L 62.714432 67.686754 z" class="m-bar m-primary"/>
+   </g>
+   <g id="matplotlib.axis_1">
+    <g id="xtick_1">
+     <g id="line2d_1">
+      <defs>
+       <path d="M 0 0 L 0 3.5" id="med42be8496" class="m-line"/>
+      </defs>
+      <g>
+       <use x="26.427031" xlink:href="#med42be8496" y="69.588125"/>
+      </g>
+     </g>
+     <g id="text_1">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 26.427031, 84.946406)" x="26.427031" y="84.946406">0</text>
+     </g>
+    </g>
+    <g id="xtick_2">
+     <g id="line2d_2">
+      <g>
+       <use x="123.973807" xlink:href="#med42be8496" y="69.588125"/>
+      </g>
+     </g>
+     <g id="text_2">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 123.973807, 84.946406)" x="123.973807" y="84.946406">200</text>
+     </g>
+    </g>
+    <g id="xtick_3">
+     <g id="line2d_3">
+      <g>
+       <use x="221.520583" xlink:href="#med42be8496" y="69.588125"/>
+      </g>
+     </g>
+     <g id="text_3">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 221.520583, 84.946406)" x="221.520583" y="84.946406">400</text>
+     </g>
+    </g>
+    <g id="xtick_4">
+     <g id="line2d_4">
+      <g>
+       <use x="319.067358" xlink:href="#med42be8496" y="69.588125"/>
+      </g>
+     </g>
+     <g id="text_4">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 319.067358, 84.946406)" x="319.067358" y="84.946406">600</text>
+     </g>
+    </g>
+    <g id="xtick_5">
+     <g id="line2d_5">
+      <g>
+       <use x="416.614134" xlink:href="#med42be8496" y="69.588125"/>
+      </g>
+     </g>
+     <g id="text_5">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 416.614134, 84.946406)" x="416.614134" y="84.946406">800</text>
+     </g>
+    </g>
+    <g id="xtick_6">
+     <g id="line2d_6">
+      <g>
+       <use x="514.160909" xlink:href="#med42be8496" y="69.588125"/>
+      </g>
+     </g>
+     <g id="text_6">
+      <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 514.160909, 84.946406)" x="514.160909" y="84.946406">1000</text>
+     </g>
+    </g>
+    <g id="text_7">
+     <text class="m-label" style="text-anchor:middle;" transform="rotate(-0, 293.523516, 99.592344)" x="293.523516" y="99.592344">kB</text>
+    </g>
+   </g>
+   <g id="matplotlib.axis_2">
+    <g id="ytick_1">
+     <g id="line2d_7">
+      <defs>
+       <path d="M 0 0 L -3.5 0" id="m786f014bed" class="m-line"/>
+      </defs>
+      <g>
+       <use x="26.427031" xlink:href="#m786f014bed" y="38.109876"/>
+      </g>
+     </g>
+     <g id="text_8">
+      <text class="m-label" style="text-anchor:end;" transform="rotate(-0, 19.427031, 42.289017)" x="19.427031" y="42.289017">A</text>
+     </g>
+    </g>
+    <g id="ytick_2">
+     <g id="line2d_8">
+      <g>
+       <use x="26.427031" xlink:href="#m786f014bed" y="59.236218"/>
+      </g>
+     </g>
+     <g id="text_9">
+      <text class="m-label" style="text-anchor:end;" transform="rotate(-0, 19.427031, 63.415358)" x="19.427031" y="63.415358">B</text>
+     </g>
+    </g>
+   </g>
+   <g id="LineCollection_1">
+    <path clip-path="url(#pf9f5e4e753)" d="M 68.811105 38.109876 L 93.197799 38.109876" class="m-error"/>
+    <path clip-path="url(#pf9f5e4e753)" d="M 55.252103 59.236218 L 70.17676 59.236218" class="m-error"/>
+   </g>
+   <g id="LineCollection_2">
+    <path clip-path="url(#pf9f5e4e753)" d="M 340.088688 38.109876 L 535.18224 38.109876" class="m-error"/>
+    <path clip-path="url(#pf9f5e4e753)" d="M 170.649939 59.236218 L 175.527278 59.236218" class="m-error"/>
+   </g>
+   <g id="line2d_9">
+    <defs>
+     <path d="M 0 5 L 0 -5" id="m1e7a6d6b54" class="m-error"/>
+    </defs>
+    <g clip-path="url(#pf9f5e4e753)">
+     <use x="68.811105" xlink:href="#m1e7a6d6b54" y="38.109876"/>
+     <use x="55.252103" xlink:href="#m1e7a6d6b54" y="59.236218"/>
+    </g>
+   </g>
+   <g id="line2d_10">
+    <g clip-path="url(#pf9f5e4e753)">
+     <use x="93.197799" xlink:href="#m1e7a6d6b54" y="38.109876"/>
+     <use x="70.17676" xlink:href="#m1e7a6d6b54" y="59.236218"/>
+    </g>
+   </g>
+   <g id="line2d_11">
+    <g clip-path="url(#pf9f5e4e753)">
+     <use x="340.088688" xlink:href="#m1e7a6d6b54" y="38.109876"/>
+     <use x="170.649939" xlink:href="#m1e7a6d6b54" y="59.236218"/>
+    </g>
+   </g>
+   <g id="line2d_12">
+    <g clip-path="url(#pf9f5e4e753)">
+     <use x="535.18224" xlink:href="#m1e7a6d6b54" y="38.109876"/>
+     <use x="175.527278" xlink:href="#m1e7a6d6b54" y="59.236218"/>
+    </g>
+   </g>
+   <g id="text_10">
+    <text class="m-title" style="text-anchor:middle;" transform="rotate(-0, 293.523516, 21.757969)" x="293.523516" y="21.757969">Stacked plot with errors and full colors</text>
+   </g>
+  </g>
+ </g>
+ <defs>
+  <clipPath id="pf9f5e4e753">
+   <rect height="41.830156" width="534.192969" x="26.427031" y="27.757969"/>
+  </clipPath>
+ </defs>
+</svg>
+</div>
 <!-- /content -->
       </div>
     </div>
index 295429a562923055293908399014e5f670fffeb0..480d070e37eb2f248ff3b666ffbbbda2cac7fd7c 100644 (file)
@@ -34,3 +34,33 @@ predictable rendering on the CIs.
     :errors: 0.1 2.1 1.0
     :colors: success info danger
     :bar_height: 0.75
+
+.. plot:: Stacked plot
+    :type: barh
+    :labels:
+        A
+        B
+        C
+    :units: kB
+    :values:
+        111.9 74.4 52.1
+        731.2 226.3 226.0
+    :colors:
+        success
+        info
+
+.. plot:: Stacked plot with errors and full colors
+    :type: barh
+    :labels:
+        A
+        B
+    :units: kB
+    :values:
+        111.9 74.4
+        731.2 226.3
+    :errors:
+        25.0 15.3
+        200.0 5.0
+    :colors:
+        success danger
+        info primary