0

I am creating table using pygal, the example in the link works well, but I did the below change in it.

line_chart = pygal.Bar()
line_chart.title = 'Browser usage evolution (in %)'
line_chart.x_labels = map(str, range(2002, 2013))
line_chart.add('Firefox', ["Hello", 'world', 'aaa', 'bbbb',   'ccc',   'cccc', 'dddd', 'eee', 'ffff', 'gggg', 'hhhh'])
line_chart.add('Chrome',  [None, None, None, None, None, None,    0,  3.9, 10.8, 23.8, 35.3])
line_chart.add('IE',      [85.8, 84.6, 84.7, 74.5,   66, 58.6, 54.7, 44.8, 36.2, 26.6, 20.1])
line_chart.add('Others',  [14.2, 15.4, 15.3,  8.9,    9, 10.4,  8.9,  5.8,  6.7,  6.8,  7.5])
line_chart.value_formatter = lambda x: '%.2f%%' % x if x is not None else '∅'
line_chart.render_table(style=True)

for the Firefox column I am adding string values in the list, it is giving me error like:

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

How can I include string records in the pygal table?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Alpha Geek
  • 457
  • 7
  • 17

1 Answers1

0

To understand your issue you're going to need to understand this line:

line_chart.value_formatter = lambda x: '%.2f%%' % x if x is not None else '∅'

what pygal is doing here is taking in a function to apply to each table value in order to get a string value out to be put into the actual table. In this case the formatter takes in a number (int or float) and uses the older formatting syntax for formatting. '%.2f%%' % x basically says "I'm going to put x here, modify the string representation such that it forces at least two decimal places, and then add a '%' symbol to the end". Additionally this lambda function checks if the value is not None before doing this, because formatting the string value in this way wouldn't work with a None value since it isn't a number, and outputs that null character.

In the original example, all table values where numerical values. Once you replaced the firefox column/row with string values the formatter couldn't work. Your error comes from the function lambda x: '%.2f%%' % x if x is not None else '∅' not being able to be applied to string values. In order to fix this you can either A: change the formatter to accept string values or B: change the values in firefox to use numbers instead of strings.

You wanted String records, so to change this you can add a check for type (ie using type(value) == int) or if you also want to use string integers, try a conversion first (ie int(value) or float(value)). See this post for more details on int checking for strings.

Your formatter lambda function might for example become:

lambda x: '%.2f%%' % x if type(x) is int or type(x) is float else '∅'

if you want to do something like the conversion checker, you are going to have to try: catch: it, so you'll need to make an actual formatter function instead of a lambda.

Community
  • 1
  • 1
Krupip
  • 4,404
  • 2
  • 32
  • 54