{"id":1341,"date":"2010-06-10T22:33:07","date_gmt":"2010-06-10T22:33:07","guid":{"rendered":"http:\/\/dalelane.co.uk\/blog\/?p=1341"},"modified":"2016-10-01T22:30:02","modified_gmt":"2016-10-01T22:30:02","slug":"how-to-generate-a-wave-graph","status":"publish","type":"post","link":"https:\/\/dalelane.co.uk\/blog\/?p=1341","title":{"rendered":"How to generate a wave graph"},"content":{"rendered":"<p><a href=\"http:\/\/www.flickr.com\/photos\/dalelane\/4689129196\/\" title=\"TV watching - split by channel by dalelane, on Flickr\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/farm5.static.flickr.com\/4035\/4689129196_a341f53380.jpg\" width=\"450\" height=\"170\" alt=\"TV watching - split by channel\" \/><\/a><\/p>\n<p>I revisited the code behind my <a href=\"http:\/\/dalelane.co.uk\/tvscrobbling\">TV scrobbling<\/a> this evening. When <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=1176\">I first wrote it<\/a>, I focused on graphs like bar graphs and pie charts. <\/p>\n<p>Tonight, I tried out wave graphs. In this post, I want to share some of the results of my first attempt, and how I wrote the script to generate them.<\/p>\n<p>I have created wave graphs showing my TV watching over the last five months. I&#8217;ve tried splitting it out by in a couple of ways:<\/p>\n<ul>\n<li>by channel (<a href=\"http:\/\/dalelane.co.uk\/drpbx\/20100610\/channel-wavegraph.pdf\">pdf<\/a>, <a href=\"http:\/\/www.flickr.com\/photos\/dalelane\/4689140214\/\">insanely-big-png<\/a>, <a href=\"http:\/\/dalelane.co.uk\/drpbx\/20100610\/channel-wavegraph.svg\">svg<\/a>)\n<\/li>\n<li>by programme title (<a href=\"http:\/\/dalelane.co.uk\/drpbx\/20100610\/channel-wavegraph.pdf\">pdf<\/a>, <a href=\"http:\/\/dalelane.co.uk\/drpbx\/20100610\/programme-wavegraph.svg\">svg<\/a>)\n<\/li>\n<\/ul>\n<p>Programme titles tend to be too long to make for a very useful graph, and there were way too many of them. But I&#8217;ve tried limiting them to the top 10 watched programmes to make for a prettier graph. The channels graph seems to work okay, though.<\/p>\n<p><a href=\"http:\/\/www.flickr.com\/photos\/dalelane\/4688496005\/\" title=\"TV watching - split by channel by dalelane, on Flickr\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/farm2.static.flickr.com\/1291\/4688496005_980981ecc8.jpg\" width=\"450\" height=\"318\" alt=\"TV watching - split by channel\" \/><\/a><\/p>\n<p>To generate the graphs, I wrote a Python script using the awesome <a href=\"http:\/\/www.aeracode.org\/projects\/graphication\/\" target=\"_blank\">graphication graphing library<\/a> by <a href=\"http:\/\/www.aeracode.org\/\" target=\"_blank\">Andrew Godwin<\/a>. <\/p>\n<p><!--more-->There isn&#8217;t a lot of documentation for it, but it&#8217;s pretty straightforward:<\/p>\n<p>1. &#8211; Install the pre-reqs &#8211; I already had Python, so just needed to install <a href=\"http:\/\/cairographics.org\/\" target=\"_blank\">pycairo<\/a><\/p>\n<p>2. &#8211; Check out the library source from <a href=\"http:\/\/svn.aeracode.org\/svn\/graphication\/\" target=\"_blank\">the SVN server<\/a>, and run the setup.py <a href=\"http:\/\/docs.python.org\/install\/\" target=\"_blank\">as usual<\/a> to install<\/p>\n<p>3. &#8211; Write a script \ud83d\ude42 <\/p>\n<p>There is already a useful <a href=\"http:\/\/www.aeracode.org\/projects\/graphication\/\" target=\"_blank\">sample script<\/a> that was enough to get me started, but I&#8217;ll expand on it slightly here.<\/p>\n<p>I have my TV watching data in an SQLite database, so it was pretty easy to write something to grab the data I need. Stripping  out the stuff that&#8217;s specific to my database structure, the basics of a graphication script is:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">from datetime import datetime\r\nfrom graphication import *\r\nfrom graphication.wavegraph import WaveGraph\r\n\r\n# an arbitrary set of dates\r\n#  see the note below about the need for consistent set of dates\r\nd1 = datetime(2010, 6, 1)\r\nd2 = datetime(2010, 6, 2)\r\nd3 = datetime(2010, 6, 3)\r\nd4 = datetime(2010, 6, 4)\r\nd5 = datetime(2010, 6, 5)\r\nd6 = datetime(2010, 6, 6)\r\nd7 = datetime(2010, 6, 7)\r\nd8 = datetime(2010, 6, 8 )\r\nd9 = datetime(2010, 6, 9)\r\n\r\n# place to store the data\r\nseries_set = SeriesSet()\r\n\r\n# some canned data sets\r\nseries_set.add_series(Series(\"BBC1\", {d1:0.5, d2:1.0, d3:0.2, d4:0.8, d5:1.1, d6:0.9, d7:0.7, d8:0.6, d9:0.4}))\r\nseries_set.add_series(Series(\"BBC2\", {d1:0.2, d2:0.9, d3:0.3, d4:0.7, d5:1.5, d6:1.2, d7:0.9, d8:1.0, d9:0.7}))\r\n\r\n# notice that if you use a date in one \r\n#  data set, you seem to have to use \r\n#  it in all of them - so I had to \r\n#  make sure I inserted a value of 0\r\n#  for days where I didn't watch a \r\n#  particular channel\r\nseries_set.add_series(Series(\"BBC3\", {d1:0, d2:0, d3:0.1, d4:0.2, d5:0.3, d6:0.2, d7:0.1, d8:0, d9:0}))\r\n\r\nseries_set.add_series(Series(\"BBC News\", {d1:0.8, d2:0.8, d3:0.8, d4:0.8, d5:1.1, d6:1.1, d7:1.1, d8:1.0, d9:0.4}))\r\n\r\n\r\n# define the appearance\r\nimport my_css as stylesheet\r\nclr = Colourer(stylesheet)\r\nclr.colour(series_set)\r\n\r\n# specify the graph scale - you can choose from \r\n#  DateScale - the basic, you need to specify the min and max date\r\n#  AutoDateScale  - works out the min and max dates for you\r\n#  AutoWeekDateScale - divides up months and weeks with major\/minor lines\r\n#  WeekdayDateScale - only plots data on weekdays, not weekends\r\ndatescale = AutoWeekDateScale(series_set)\r\n\r\n# create the wave graph\r\nwg = WaveGraph(series_set, datescale, stylesheet, label_curves=True)\r\n\r\n# write it to files, in variety of file types\r\noutput = FileOutput(stylesheet)\r\noutput.add_item(wg, x=0, y=0, width=445, height=150)\r\noutput.write(\"pdf\", \"yourgraph.pdf\")\r\noutput.write(\"png\", \"yourgraph.png\")\r\noutput.write(\"svg\", \"yourgraph.svg\")<\/pre>\n<p>If you run that, you get something like this:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/dalelane.co.uk\/blog\/post-images\/100610-wavegraph.png\" alt=\"wavegraph\"\/><\/p>\n<p>And that&#8217;s all there is to it. <\/p>\n<p>Although I could automate this, I&#8217;ve chosen not to for the moment, so the graphs wont be appearing on <a href=\"http:\/\/dalelane.co.uk\/tvscrobbling\/\">dalelane.co.uk\/tvscrobbling<\/a> yet. <\/p>\n<p>This is because I haven&#8217;t managed to find a decent balance between making the images so huge that hosting the files would bring my site down, or making the images so small that the labels are unreadable. (<em>For now, I&#8217;ve run the script once and used flickr and dropbox to host the files.<\/em>)  I&#8217;m not sure what the best answer is for this, but I&#8217;ll have a think about it. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I revisited the code behind my TV scrobbling this evening. When I first wrote it, I focused on graphs like bar graphs and pie charts. Tonight, I tried out wave graphs. In this post, I want to share some of the results of my first attempt, and how I wrote the script to generate them. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[318,212,443],"class_list":["post-1341","post","type-post","status-publish","format-standard","hentry","category-code","tag-graphs","tag-python","tag-scrobble"],"_links":{"self":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1341"}],"version-history":[{"count":0,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1341\/revisions"}],"wp:attachment":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}