Slopegraphs in Python – Attention to Detail

In the previous installment, a foundation was laid for “parameterizing” fonts, colors and overall slopegraph size. However, a big failing in all this code (up until now) was the reliance on character string length to determine label width. When working with fonts, the font metrics are more important since a lowercase ‘l’ will have a smaller font width than an uppercase ‘D’. So, while ‘llll’ is “longer” than ‘DDD’, it may not be wider (especially in a sans-serif font, but likely in any font):

To solve this problem, we need to use a temporary Cairo surface to compute font metrics for each label & value so we know what the maximum width of both for the starting and ending points. It’s a simple concept & calculation, but very important to ensure everything lines up well.

  1. # find the *real* maximum label width (not just based on number of chars)
  3. maxLabelWidth = 0
  4. maxNumWidth = 0
  6. for k in sorted(startKeys):
  7. 	s1 = starts[k]
  8. 	xbearing, ybearing, sWidth, sHeight, xadvance, yadvance = (cr.text_extents(s1))
  9. 	if (sWidth > maxLabelWidth) : maxLabelWidth = sWidth
  10. 	xbearing, ybearing, startMaxLabelWidth, startMaxLabelHeight, xadvance, yadvance = (cr.text_extents(str(k)))
  11. 	if (startMaxLabelWidth > maxNumWidth) : maxNumWidth = startMaxLabelWidth
  13. sWidth = maxLabelWidth
  14. startMaxLabelWidth = maxNumWidth
  16. maxWidth = 0
  17. maxNumWidth = 0
  19. for k in sorted(endKeys):
  20. 	e1 = ends[k]
  21. 	xbearing, ybearing, eWidth, eHeight, xadvance, yadvance = (cr.text_extents(e1))
  22. 	if (eWidth > maxLabelWidth) : maxLabelWidth = eWidth
  23. 	xbearing, ybearing, endMaxLabelWidth, endMaxLabelHeight, xadvance, yadvance = (cr.text_extents(str(k)))
  24. 	if (endMaxLabelWidth > maxNumWidth) : maxNumWidth = endMaxLabelWidth
  26. eWidth = maxLabelWidth
  27. endMaxLabelWidth = maxNumWidth

I tossed some “anomalies” into the sample data set to show both how adaptable the vertical scale is as well as demonstrate the label alignments:

Updates are in github.

Cover image from Data-Driven Security
Amazon Author Page

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.