Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Nodebox for Data Visualization


Published on

A talk for PyData 2013, on using Nodebox OpenGL (and Nodebox 1) for doing data vis with python. Find me at

Nodebox for Data Visualization

  1. 1. NODEBOX FOR DATA VISUALIZATIONLynn  Cherny  for  PyData  2013  @arnicas  
  3. 3.    
  4. 4. FLOCK EXAMPLE Take  that ,  ma tplo tlib  ( ?!)  h3p://  
  5. 5. NODEBOX OPENGL from import * def draw(canvas): canvas.clear() nofill() Set  context  values   stroke(0, 0.25) strokewidth(1) X,  Y,  width,  height   Local  override  of  context   rect( 50, 50, 50, 50) values   rect(110, 50, 50, 50, stroke=Color(0), strokestyle=DASHED) rect(170, 50, 50, 50) 0,0  in  lower  leB  by  default  (top   leB  in  NB  1!)  
  6. 6. NODEBOX 1 IS A SMART IDE Implicit  canvas,  draw,  etc.  
  7. 7. DOWNLOAD NODEBOX Mac  too,  I’ll   TentaQve  evidence   demo   of  linux  too  
  8. 8. GENERATIVE ART JusQn  D  on  flickr.    
  10. 10. LIBRARIES IN NODEBOX 1 (MAC OSX) Note:  these  libraries  must  be  put  in  ~/Library/Application   Support/Nodebox  to  be  imported.  All  the  libs  live  here.  
  11. 11. IMAGE TOOLS
  13. 13. COLOR TOOLS, SVG
  14. 14. GRIDS
  16. 16. DEMOS IN NODEBOX 1
  17. 17. If  you  do  data  visualization,  but  not  “art,”  WHY WOULD YOU NEED THIS TOOL?
  18. 18. SKETCHES IN CODE Examples  from   Processing  sketches   by  JanWillem  Tulp  
  19. 19. “Ghost  CounQes,”  by  @JanWillemTulp  
  20. 20. UNUSUAL GRAPH TYPES Slopegraph  from  Juice  Analytics,  code  for  NB  1  
  21. 21. TOOL CREATION My  sparklines  generator  in   NB  OGL   Example  in  NB  OGL  
  22. 22. NODEBOX 1 “GUI” Example  for  NB1  
  23. 23. CLOSEST SIMILAR TOOLS Drawbot  (Preceded  and  inspired  Nodebox,    MacOSX  only)   Shoebot  (MacOSX),  with  Spryte  for  Windows    (some  examples  run  unchanged  in  NB1!)   Pythonista  on  Ipad!       Processing  (cross  platform,  includes  .js  port)    (  by  jpheinberg  is  jython-­‐based.)  
  24. 24. PROCESSING LOOKS LIKE JAVA L Plus,  obviously,  I  want  Python  libs   h3p://  
  25. 25. Very,  very  short  intro  to  the  concepts…  DRAWING BASICS
  26. 26. NODEBOX 1 PRIMITIVES Most  of  them  in  NB  OGL   Note:  no  triangle()  as  in  Nodebox  OGL;  “oval”  instead  of  “ellipse”  as  in  OGL  
  27. 27. SHAPE PRIMITIVES IN NODEBOX OGL NOTE:  ellipse()  not  oval()  as  in  NB1  
  28. 28. THE DRAW() LOOP Nodebox  1  can  be  used  for  simple  static  image   without  animation  –  no  canvas  declaration    or   draw  loop  needed.    (Use  speed(<fps>)  to  turn  on   the  animation.)     Nodebox  OGL    always  runs  an  animation  loop  in   a  draw  function  (you  can  exit  out  with  a  return   after  canvas.frame==1  in  “draw”  if  you  want)       mycanvas = Canvas(width=600, height=480) mycanvas.fps = 20,setup=setup)
  29. 29. DRAWING CONTEXT CHANGES State  context  changers:     colormode(), fill(), stroke(), strokewidth(),   nofill(), nostroke() font(), fontsize() transform(), translate(), rotate(), scale(), skew()     Temporary  state  changes:        push() fill(0) translate(200,200) pop()  
  30. 30. NOTICE THE CONTEXT AGAIN…from import *def draw(canvas): canvas.clear() nofill() Set  context  values   stroke(0, 0.25) strokewidth(1) X,  Y,  width,  height   Local  override  of  context   rect( 50, 50, 50, 50) values   rect(110, 50, 50, 50, stroke=Color(0), strokestyle=DASHED) rect(170, 50, 50, 50)
  31. 31. LEARNING THE “REST” §  Examples  with  both  NB  1  and  NB  OGL   distribs:  commented  and  by  topic   §  Tutorials  on  the  NB  1  site     §  The  extensive  intro  page  for  NB  OGL  (that   builds  off  NB1’s  api  background)  
  32. 32. Getting  Real(ly  dirty  and  sketchy)  MY TOY EXAMPLES
  33. 33. FICTION INVESTIGATION… Shane  Bergsma’s  db  of  noun  gender  (based  on   Google  news  crawling):  [see  refs]        “word  male  female  neutral  plural”,  e.g.:        publication  93    20    3152  110     1.  Load  Shane’s  db  into  redis   2.  Convert  books  to  txt  (blank  line  bw  paragraphs)   3.   Extract  nouns  with     4.  Code  each  with  tuple  (m,  f,  n)  &  %’s     5.  Write  out  as  csv  for  use  in  Nodebox  scripts  
  34. 34. COORDINATES IN COLOR AND 3-SPACE Neutral   Male   Female  
  35. 35. FOOTNOTE: HSV IN THE BLUE-REDRANGE / WITH DARKNESS Code  borrowed  from  an  example  on  StackOverflow  –  tuned  to  get  only  hue  from   blue  to  red  from  complete  HSV  range  
  36. 36. GET CARTESIAN X, Y COORD FROM ATUPLE def to_cart(triple): (m, f, n) = triple x = ( f + n / 2.0) y = math.sqrt(3) * n / 2.0 return x, y Code  in  my  file  
  37. 37. INTERPOLATION You  often  need  to  map  from  a  data  range  to  another  range   (of  pixels,  or  color  points…).  Mapping  my  X  and  Y  to  colors:     from scipy.interpolate import interp1d hue_scale = interp1d([0,1],[.67,1])   For  pythonic  hsv  color  and  then  nodebox  rgb:     hsv = (hue_scale(x)[0], 1, 1-y[0]) rgb = Color(colorsys.hsv_to_rgb(*hsv)) I  am  flipping   the  V!  
  38. 38.  
  39. 39. EVENTS : LAYERS, MOUSE, KEYS Layers  in  NB  OGL  are  one  good  way  you  might   handle  “mouseover”  functionality   Layers  have  their  own  draw()  functionality,  and  the   canvas  knows  that  layer  is  in  focus  (under  the  mouse,  via   canvas.focus)     Mouse  events  are  also  handled  nicely  by   canvas.mouse  –  mouse.x,  mouse.y,  etc.  are   available                                                                                          See  my  example  
  40. 40.  
  41. 41. MOUSE & KEYBOARD EVENTS mouse  =  canvas.mouse   mouse.x                                                                    #  Horizontal  position.   mouse.y                                                                    #  Vertical  position.  NB  OGL:  h3p://   mouse.relative_x                                #  Relative  (0.0-­‐1.0)  to  Canvas.width.   mouse.relative_y                                #  Relative  (0.0-­‐1.0)  to  Canvas.height.   mouse.dx                                                              #  Drag  distance  from  previous  x.   mouse.dy                                                              #  Drag  distance  from  previous  y.   mouse.pressed                                        #  True  if  the  mouse  button  is  pressed.   mouse.dragged                                      #  True  if  the  mouse  is  dragged.   mouse.cursor                                                #  DEFAULT,  CROSS,  HAND,  HIDDEN,  TEXT,  WAIT   mouse.button                                              #  LEFT,  RIGHT,  MIDDLE   mouse.modifiers                                    #  List  of:  CTRL,  SHIFT,  OPTION   keys  =  canvas.keys   keys[]                                                                                #  All  keys  pressed  (SHIFT  +  "a"  =>  [SHIFT,  "a"]).   keys.char                                                                  #  Last  key  pressed  (SHIFT  +  "a"  =>  "A").   keys.code                                                              #  Last  key  pressed  (SHIFT  +  "a"  =>  "a").   keys.modifiers                                            #  List  of  modifier  keys  (CTRL,  SHIFT,  OPTION).   keys.pressed                                                  #  True  if  a  key  is  pressed  on  the  keyboard.  
  42. 42. LAYERS GOT EVENTS TOO layer.enabled                                                            #  True  =>  will  receive  events.   layer.pressed                                                              #  True  =>  mouse  pressed  on  layer.  NB  OGL:  h3p://   layer.dragged                                                            #  True  =>  mouse  dragged  on  layer.   layer.focus                                                                        #  True  =>  mouse  hovering  over  layer.   layer.on_mouse_enter(mouse)   layer.on_mouse_leave(mouse)   layer.on_mouse_motion(mouse)   layer.on_mouse_press(mouse)   layer.on_mouse_release(mouse)   layer.on_mouse_drag(mouse)   layer.on_mouse_scroll(mouse)   layer.on_key_press(keys)   layer.on_key_release(keys)  
  43. 43. MOUSEOVER  
  44. 44. A FAILED EXPERIMENT CAN STILL BEFUN… ADDING ANIMATION.Angels  &  Demons  (Brown)  Twilight  (Meyer)   “jade”  Pride  &  Prejudice  (Austen)  The  Secret  Agent  (Conrad)  
  45. 45. GETTING BLUNTER… 2 ON ONE: Doesn’t  show  much…   sigh.  
  46. 46. JUST GET EVEN BLUNTER…Centroid  of  each…  a  li3le  more  revealing  maybe?  Definitely  not  for  publicaQon!  
  47. 47. THERE CAN BE VALUE IN “MISTAKES”WHEN VISUALIZING DATA AT PIXEL LEVEL Thanks  to  MarQn  Wa3enberg   and  Fernanda  Viegas  for  this   observaQon…  
  48. 48. A MORE INTERESTING MISTAKE… If  you  don’t  filter  out  duplicate  menQons  of  the  same   noun….  
  49. 49. Twilight   Angels  &  Demons  
  50. 50. Twilight   Angels  &  Demons   (uniqued)   (uniqued)  
  51. 51. RATIO OF NOUNS TO UNIQUE NOUNS(AS EXPECTED NOW) Unique   Nouns/   Nouns/ Nouns   Words       Nouns   Unique   Words   Angels  &   19546   2842   6.9   151610   7.8   Demons   Twilight   18252   1943   9.4   121205   6.6  
  52. 52. Twilight  (most  repeated)   Angels  &  Demons  (most  repeated)  
  53. 53. HOOKING UP OTHER PYTHON LIBS 1.  Load  a  book  into  redis  by  line  #   2.  Plot  dialog  vs.  exposition  in  a  simple  colored   bar   3.  Use  the  redis  db  to  see  what’s  what  in  the   book  on  rollover!     Simple,  and  very  fast!  
  54. 54. DIALOG TO EXPOSITION… Twilight     Angels  &  Demons   Secret  Agent   Pride  &  Prejudice   Moby  Dick   (Meyer)   (Brown)   Para  groups:  7  
  55. 55. Phew!  That  was  a  lot  of  stuff.  WRAP UP…
  56. 56. WHY OR WHY NOT NODEBOX? Advantages     §  Data  as  “art”  –  not  supported  by  Matplotlib  (or   future  ggplot2  ports  to  python)   §  Data  “sketching”  –    speedy  unstructured  pics   §  Animation  is  basic   §  Events  come  along  too   §  You  get  to  write  in  Python  (unlike  w/  Processing)   §  So  you  can  use  other  Python  libs    
  57. 57. BUT… §  No  3d  (unlike  matplotlib)   §  PDF  or  SVG  Export  are  required  for  good  print/reuse  (available  in   NB  1,  not  in  NB  OGL  yet)   §  No  web  embedding  /  js  version  (unlike  processing.js)   §  Can’t  use  with  IPython  notebook  (yet)   §  Challenge  of  other  python  libs  with  NB  1  -­‐  sad  PYTHONPATH   problem  in  Nodebox  1  (see  appendix  for  tips)   §  Authors  in  Leuven  more  focused  on  NB  3/  than  on  NB1  /   OGL  versions.          Can  we  invigorate  Nobebox  OpenGL?     §  A  general  lack  of  code  examples  to  draw  from…  hopefully  mine  will   help!  
  58. 58. THAT’S IT - A BIG THANKS!@deepfoo  for  the  reminder  of  Nodebox1,  Tom  De  Smedt  and  Frederik  De  Bleser  for  email  help,  @minrk  for  help,  @jsundram  for  code  cleanup  advice  (not  all  of  which  I  took),  @pwang  and  #PyData  for  having  me  
  59. 59. Find  me  @arnicas,  blog  GET THE CODE FILES HERE!PDF OF THESE SLIDES HERE. Apologies  for  the  import  *  and  the  globals…    I  was  following  some   suggesQons  in  the  demos  I  looked  at  which  may  not  have  been  ideal.  
  60. 60. REFERENCES§  JanWillem  Tulp  Ghost  Counties  images:  §  Code  for  ternary  plots  in  python  and  excel:  and  Will  Vaughn’s  at  §  Nodebox  flickr  gallery  §  Running  Nodebox  1  from  command  line:  §  by  Tom  de  Smedt  (a  Nodebox  original  author)  §  Nodebox  authors  Tom  De  Smedt  and  Frederik  De  Bleser  in  Belgium  §  Shane  Bergsma  and  Dekang  Lin,  “Bootstrapping  Path-­‐Based  Pronoun   Resolution,”  In  Proceedings  of  the  Conference  on  Computational   Lingustics  /  Association  for  Computational  Linguistics  (COLING/ ACL-­‐06),  Sydney,  Australia,  July  17-­‐21,  2006.  (page  w/  db)  
  61. 61. APPENDIX: NODEBOX 1’S IMPORT PATH Custom  path,  includes  its  own  python  (64  bit)…  so….   –  You  can  install  your  packages  into  NodeBox’s  path,  ie.,  ~/ Library/Application  Support/NodeBox/  —  meaning  that  you   can  use  them  from  NodeBox,  but  not  from  other  scripts…   –  You  can  import  sys  in  your  NodeBox  code  and  manually  modify   the  sys.path  value  to  add  your  existing  packages…   –  You  can  install  packages  into  your  system  site-­‐packages   directory,  and  sym-­‐link  them  from  NodeBox’s  directory…   –  You  can  make  NodeBox  use  your  system  packages  instead  of   it’s  own  by  sym-­‐linking  ~/Library/Application  Support/ NodeBox  to  your  site-­‐packages  directory  of  choice  (ex.,  / Library/Python/2.5/site-­‐packages)   –  Some  flavor  of  above  plus  VIRTUALENV   Tips  from  h3p://   Thread  here  too:  h3p://­‐09-­‐04-­‐01-­‐42-­‐29  
  62. 62. APPENDIX: NODEBOX1 AT COMMANDLINE… §  Instructions  and  samples  here:   §  Best  to  use  a  virtualenv  again  
  63. 63. THE NODEBOX “FAMILY”Nodebox  1   Platform  &  “style”   Mac  OSX  only  (kind  of   Status   No  longer  in  dev,  spotty   URLs   Mac  OSX  Lion  file:   Lion)  –  write  python  code   archiving  online  (the  original)   downloads/ in  a  simple  IDE   NodeBox-­‐   Home: index.php/Home   Github  copy  of  svn  source: nodebox-­‐pyobjc    Nodebox  2     Mac  OSX  –  python  visual   GONE!    Apparently  was   Home:  (the  disappeared)   programming  “blocks”   slow  and  confusing?  Nodebox  3     Mac  and  Windows  –  no   Not  so  interesting  to  me:  I   Home:   IDE,  no  python  exposed,   want  to  write  python  (the  current    beta)   all  visual  programming?   code.  Nodebox   Mac  and  Windows  –  write   Not  up  to  date  with   Home:   plain  python  code   Nodebox  1  yet  (e.g.,  lack  (the   nodebox/    incomplete)   of  libraries,  lack  of   Github  code:   functionality;  not  so  well documented);  can’t  run  in   nodebox-­‐opengl   IPython  notebook  due  to     probable  multithreading     issue(s)