diff --git a/pygal/adapters.py b/pygal/adapters.py
new file mode 100644
index 0000000..c7e2f46
--- /dev/null
+++ b/pygal/adapters.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# This file is part of pygal
+#
+# A python svg graph plotting library
+# Copyright © 2012 Kozea
+#
+# This library is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with pygal. If not, see .
+"""
+Value adapters to use when a chart doesn't accept all value types
+
+"""
+
+
+def positive(x):
+ if x is None:
+ return
+ if x < 0:
+ return 0
+ return x
+
+
+def not_zero(x):
+ if x == 0:
+ return
+ return x
+
+
+def none_to_zero(x):
+ return x or 0
diff --git a/pygal/graph/verticalpyramid.py b/pygal/graph/verticalpyramid.py
new file mode 100644
index 0000000..cd2c71f
--- /dev/null
+++ b/pygal/graph/verticalpyramid.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+# This file is part of pygal
+#
+# A python svg graph plotting library
+# Copyright © 2012 Kozea
+#
+# This library is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with pygal. If not, see .
+"""
+Pyramid chart
+
+"""
+
+from __future__ import division
+from pygal.util import compute_scale, safe_enumerate
+from pygal.adapters import positive
+from pygal.graph.bar import Bar
+
+
+class VerticalPyramid(Bar):
+ """Pyramid graph"""
+
+ _adapters = [positive]
+
+ def _format(self, value):
+ return super(VerticalPyramid, self)._format(abs(value))
+
+ def _compute(self):
+ positive_vals = zip(*[serie.safe_values
+ for index, serie in enumerate(self.series)
+ if index % 2])
+ negative_vals = zip(*[serie.safe_values
+ for index, serie in enumerate(self.series)
+ if not index % 2])
+ positive_sum = map(sum, positive_vals) or [0]
+ negative_sum = map(sum, negative_vals)
+
+ self._box.ymax = max(max(positive_sum), max(negative_sum))
+ self._box.ymin = - self._box.ymax
+
+ x_pos = [
+ x / self._len
+ for x in range(self._len + 1)
+ ] if self._len > 1 else [0, 1] # Center if only one value
+ y_pos = compute_scale(
+ self._box.ymin, self._box.ymax, self.logarithmic, self.order_min
+ ) if not self.y_labels else map(float, self.y_labels)
+
+ self._x_ranges = zip(x_pos, x_pos[1:])
+
+ self._x_labels = self.x_labels and zip(self.x_labels, [
+ sum(x_range) / 2 for x_range in self._x_ranges])
+ self._y_labels = zip(map(self._format, y_pos), y_pos)
+
+ def _plot(self):
+ stack_vals = [[0, 0] for i in range(self._len)]
+ for index, serie in enumerate(self.series):
+ serie_node = self._serie(index)
+ stack_vals = self.bar(
+ serie_node, serie, [
+ tuple(
+ (self._x_ranges[i][j],
+ v * (-1 if index % 2 else 1)) for j in range(2))
+ for i, v in safe_enumerate(serie.values)], index,
+ stack_vals)