Search code examples
pythonpygal

Using Python, how can I update data programmatically for a Pygal chart?


Using Python, how can I update data programmatically for a Pygal chart?

The code below works fine as a static Stacked-Bar chart, but I can't figure out how to accommodate changing values.

Considerations/issues:

  • My values, that I would like to update, come from a REST call as strings every five minutes.
  • I haven't figured out how to update data for the Pygal chart, because inserting strings into the lists cause an error (shown below).
  • I don't know how to insert a list of new integers into the "class" below.
  • I'm showing only five data points for this example, but I might need to have as many as 100 data points eventually.
  • Setting variables might work for a static number of elements but my elements will increase and decrease sporadically.

import pygal

line_chart = pygal.HorizontalStackedBar()
line_chart.title = 'Application Health'
line_chart.x_labels = ( "cluster05", "cluster04", "cluster03", "cluster02", "cluster01")
line_chart.add('Critical', [2, 5, 4, 1, None])
line_chart.add('Warning',[1, 7, 2, None, 2])
line_chart.add('OK', [25, 30, 19, 20, 25])
line_chart.render_to_file('test_StackedBar.svg')

The line type is the following class.

>>> type(line_chart.add('OK', [25, 30, 19, 20, 25]))
<class 'pygal.graph.horizontalstackedbar.HorizontalStackedBar'>
>>> 

newData = "21, 55, 35, 82, 47, 70, 60"
line_chart.add('OK',[newData])

TypeError: unsupported operand type(s) for +: 'int' and 'str'

newData = "21, 55, 35, 82, 47, 70, 60"
y = list(newData)
line_chart.add('OK',[y])
line_chart.render_to_file('test_StackedBar.svg')

TypeError: unsupported operand type(s) for +: 'int' and 'list'

Solution

  • You have a TypeError. it expects a list of numbers.

    It's easy to think of variables as substitutions: y = [1,2,3] means anywhere there is a y, just put [1,2,3] instead. So when you do [y], it happily replaces it with [[1,2,3]]

    You're giving it a list containing a single string: ["21, 55, 35, 82, 47, 70, 60"], then passing that inside a list: [["21, 55, 35, 82, 47, 70, 60"]], which is not what it expects.

    It wants a list of integers:

    y = [21, 55, 35, 82, 47, 70, 60]
    line_chart.add('OK',y)
    

    To update the chart, you'll likely have to rebuild it (I'm not familiar with pygal, so it may support editing in place, but rebuilding will always work)

    def update_chart(crit_values, warning_values, ok_values):
        line_chart = pygal.HorizontalStackedBar()
        line_chart.title = 'Application Health'
        line_chart.x_labels = ( "cluster05", "cluster04", "cluster03", "cluster02", "cluster01")
        line_chart.add('Critical', crit_values)
        line_chart.add('Warning', warning_values)
        line_chart.add('OK', ok_values)
        line_chart.render_to_file('test_StackedBar.svg')
    

    Will allow you to rebuild it and pass it new lists for each type, by doing:

    update_chart([2, 5, 4, 1, None], [1, 7, 2, None, 2], [25, 30, 19, 20, 25]) or update_chart(x, y, z) where x,y,z are integer lists like I showed above.