pygal
pygal copied to clipboard
merge line and bar
Is it possible to merge two charts, for instance a Bar chart and an XY chart on the same svg ?
As of now no. But nothing is impossible !
Hi there, this is just to support this feature request. I really like pygal a lot but have specific use cases where this would be convenient. For example, when I want to show the absolute count for several items using (ordered) bars and an axis with counts, but also a line showing the cumulated proportion of the total sum of counts (using a secondary axis with percentages rather than counts).
Yes and it would be a good opportunity to refactor secondary series.
I managed to did it by using a nasty hack but I write down the code here, it can help someone:
Instead of doing chart = Bar()
, just do chart = LineBar()
.
from __future__ import division
from pygal.graph.graph import Graph
# Import Bar and Line chart
from pygal.graph.bar import Bar
from pygal.graph.line import Line
# Create a class extending Graph
class LineBar(Graph):
# All the series are bar except the last which is line
# It was my use case but you can change it depending on your need
def _plot(self):
for i, serie in enumerate(self.series, 1):
if i == len(self.series):
self.line(serie)
else:
self.bar(serie)
# Here we add the necessary properties to LineBar
# It's an ugly trick but it does the job and that's why I love python!
# Add bar properties
LineBar.bar = Bar.bar
LineBar._compute = Bar._compute
LineBar._bar = Bar._bar
LineBar._series_margin = Bar._series_margin
LineBar._serie_margin = Bar._serie_margin
LineBar._tooltip_and_print_values = Bar._tooltip_and_print_values
# Add line properties
LineBar.line = Line.line
LineBar._fill = Line._fill
LineBar._self_close = False
Good luck!
@realitix how to use LineBar?
@Yuliang-Lee
chart = LineBar(style=style)
chart.title = "Stat"
chart.x_labels = ['0', '1', '2', '3', '4']
chart.add('First Bar', [1, 2, 3, 4, 5])
chart.add('Second bar', [5, 4, 3, 2, 1])
chart.add('Line stat', [4, 2, 0, 5, 4])
chart.render_to_file(''/tmp/out.svg")
@realitix Yours does not handle secondary
. And you could extend LineBar from Line and Bar as LineBar(Bar, Line)
Indeed @ebsaral, like I said it's a ugly hack without thinking a lot. ;-)
@realitix ... chart = LineBar(style=style) chart.title = "Stat" chart.x_labels = ['0', '1', '2', '3', '4'] chart.add('First Bar', [1, 2, 3, 4, 5]) chart.add('Second bar', [5, 4, 3, 2, 1]) chart.add('Line stat', [4, 2, 0, 5, 4]) chart.render_to_file(''/tmp/out.svg")
But, I am getting following error TypeError: init() takes at most 2 arguments (3 given) ; After this I had tried, chart = LineBar(Line) AttributeError: 'LineBar' object has no attribute 'style'
I am not sure how to use it, could you please help me. thank you
See also #516. #516 uses Line and Bar and not Bar and XY, but I think extending the example to include XY should be pretty straightforward.