Examples for lolviz

Install

If on mac, I had to do this:

$ brew install graphviz  # had to upgrade graphviz on el capitan

Then

$ pip install lolviz

Sample visualizations


In [1]:
from lolviz import *

In [2]:
objviz([u'2016-08-12',107.779999,108.440002,107.779999,108.18])


Out[2]:
G node4348963272 0 '2016-08-12' 1 107.779999 2 108.440002 3 107.779999 4 108.18

In [3]:
table = [
    ['Date','Open','High','Low','Close','Volume'],
    ['2016-08-12',107.779999,108.440002,107.779999,108.18,18612300,108.18],
]
objviz(table)


Out[3]:
G node4348963784 0 1 node4349342088 0 1 2 3 4 5 'Date' 'Open' 'High' 'Low' 'Close' 'Volume' node4348963784:0->node4349342088:w node4349341960 0 '2016-08-12' 1 107.779999 2 108.440002 3 107.779999 4 108.18 5 18612300 6 108.18 node4348963784:1->node4349341960:w

In [4]:
d = dict([(c,chr(c)) for c in range(ord('a'),ord('f'))])
objviz(d)


Out[4]:
G node4349363976 97 'a' 98 'b' 99 'c' 100 'd' 101 'e'

In [5]:
tuplelist = d.items()
listviz(tuplelist)


Out[5]:
G node4349276616 0 97→'a' 1 98→'b' 2 99→'c' 3 100→'d' 4 101→'e'

In [6]:
tuplelist = d.items()
listviz(tuplelist, showassoc=False)


Out[6]:
G node4349277480 0 (97, 'a') 1 (98, 'b') 2 (99, 'c') 3 (100, 'd') 4 (101, 'e')

In [7]:
objviz(tuplelist)


Out[7]:
G node4349343752 0 1 2 3 4 node4347383112 0 1 97 'a' node4349343752:0->node4347383112:w node4347382344 0 1 98 'b' node4349343752:1->node4347382344:w node4347395912 0 1 99 'c' node4349343752:2->node4347395912:w node4347377096 0 1 100 'd' node4349343752:3->node4347377096:w node4347387976 0 1 101 'e' node4349343752:4->node4347387976:w

In [8]:
T = ['11','12','13','14',['a','b','c'],'16']
lolviz(T)


Out[8]:
G node4349262472 0 1 2 3 4 5 '11' '12' '13' '14' ['a', 'b', 'c'] '16'

In [9]:
objviz({'hi','mom'})


Out[9]:
G node4349344520 0 1 'hi' 'mom'

In [10]:
objviz({'superuser':True, 'mgr':False})


Out[10]:
G node4349372744 'superuser'     'mgr'     node4306300176 True node4349372744:c->node4306300176 node4306301120 False node4349372744:c->node4306301120

In [11]:
objviz(set(['elem%d'%i for i in range(20)])) # long set shown vertically


Out[11]:
G node4349342664 0 'elem6' 1 'elem19' 2 'elem1' 3 'elem8' 4 'elem17' 5 'elem15' 6 'elem11' 7 'elem12' 8 'elem14' ... ... 19 'elem10'

In [12]:
# test linked list node
class Node:
    def __init__(self, value, next=None):
        self.value = value
        self.next = next

head = Node('tombu')
head = Node('parrt', head)
head = Node("xue", head)
objviz(head)


Out[12]:
G cluster1 node4349426432 Node value 'tombu' next     node4349426656 Node value 'parrt' next     node4349426656:c->node4349426432 node4349426544 Node value 'xue' next     node4349426544:c->node4349426656

In [13]:
a = {Node('parrt'),Node('mary')}
objviz(a)


Out[13]:
G node4349343176 0 1 node4349425816 Node value 'parrt' next     node4349343176:0->node4349425816:w node4349423912 Node value 'mary' next     node4349343176:1->node4349423912:w

In [14]:
head2 = ('parrt',('mary',None))
objviz(head2)


Out[14]:
G node4349344392 0 1 node4347131080 0 1 'mary'   node4349344392:1->node4347131080:w

In [15]:
data = [[]] * 5  # INCORRECT list of list init
lolviz(data)


Out[15]:
G node4348963656 0 1 2 3 4 node4349343752 empty list node4348963656:0->node4349343752:w node4348963656:1->node4349343752:w node4348963656:2->node4349343752:w node4348963656:3->node4349343752:w node4348963656:4->node4349343752:w

In [16]:
data[0].append( ('a',4) )
data[2].append( ('b',9) ) # whoops! should be different list object
lolviz(data)


Out[16]:
G node4348963656 0 1 2 3 4 node4349343752 0 1 ('a', 4) ('b', 9) node4348963656:0->node4349343752:w node4348963656:1->node4349343752:w node4348963656:2->node4349343752:w node4348963656:3->node4349343752:w node4348963656:4->node4349343752:w

In [17]:
table = [ [] for i in range(5) ] # correct way to init
lolviz(table)


Out[17]:
G node4348961288 0 1 2 3 4 node4348963272 empty list node4348961288:0->node4348963272:w node4348556168 empty list node4348961288:1->node4348556168:w node4349345160 empty list node4348961288:2->node4349345160:w node4349343816 empty list node4348961288:3->node4349343816:w node4349263688 empty list node4348961288:4->node4349263688:w

In [18]:
key = 'a'
value = 99
def hashcode(o): return ord(o) # assume keys are single-element strings
print("hashcode =", hashcode(key))
bucket_index = hashcode(key) % len(table)
print("bucket_index =", bucket_index)
bucket = table[bucket_index]
bucket.append( (key,value) ) # add association to the bucket
lolviz(table)


hashcode = 97
bucket_index = 2
Out[18]:
G node4348961288 0 1 2 3 4 node4348963272 empty list node4348961288:0->node4348963272:w node4348556168 empty list node4348961288:1->node4348556168:w node4349345160 0 ('a', 99) node4348961288:2->node4349345160:w node4349343816 empty list node4348961288:3->node4349343816:w node4349263688 empty list node4348961288:4->node4349263688:w

In [19]:
key = 'f'
value = 99
print("hashcode =", hashcode(key))
bucket_index = hashcode(key) % len(table)
print("bucket_index =", bucket_index)
bucket = table[bucket_index]
bucket.append( (key,value) ) # add association to the bucket
lolviz(table)


hashcode = 102
bucket_index = 2
Out[19]:
G node4348961288 0 1 2 3 4 node4348963272 empty list node4348961288:0->node4348963272:w node4348556168 empty list node4348961288:1->node4348556168:w node4349345160 0 1 ('a', 99) ('f', 99) node4348961288:2->node4349345160:w node4349343816 empty list node4348961288:3->node4349343816:w node4349263688 empty list node4348961288:4->node4349263688:w

If we don't indicate we want a simple 2-level list of list with lolviz(), we get a generic object graph:


In [20]:
objviz(table)


Out[20]:
G node4349342472 0 1 2 3 4 node4348963272 empty list node4349342472:0->node4348963272:w node4348556168 empty list node4349342472:1->node4348556168:w node4349345160 0 1 node4349342472:2->node4349345160:w node4349343816 empty list node4349342472:3->node4349343816:w node4349263688 empty list node4349342472:4->node4349263688:w node4347390088 0 1 'a' 99 node4349345160:0->node4347390088:w node4347404104 0 1 'f' 99 node4349345160:1->node4347404104:w

In [21]:
courses = [
    ['msan501', 51],
    ['msan502', 32],
    ['msan692', 101]
]
mycourses = courses
print(id(mycourses), id(courses))
objviz(courses)


4348961736 4348961736
Out[21]:
G node4349341768 0 1 2 node4347682696 0 1 'msan501' 51 node4349341768:0->node4347682696:w node4349436232 0 1 'msan502' 32 node4349341768:1->node4349436232:w node4349343880 0 1 'msan692' 101 node4349341768:2->node4349343880:w

You can also display strings as arrays in isolation (but not in other data structures as I figured it's not that useful in most cases):


In [22]:
strviz('New York')


Out[22]:
G node4349438192 0 1 2 3 4 5 6 7 ' N e w Y o r k '

In [23]:
class Tree:
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right
        
root = Tree('parrt',
            Tree('mary',
                 Tree('jim',
                      Tree('srinivasan'),
                      Tree('april'))),
            Tree('xue',None,Tree('mike')))

treeviz(root)


Out[23]:
G node4349498312 Tree value 'parrt' left right node4349498144 Tree value 'mary' left right node4349498312:c->node4349498144 node4349498256 Tree value 'xue' left right node4349498312:c->node4349498256 node4349498088 Tree value 'jim' left right node4349498144:c->node4349498088 node4349497976 Tree value 'srinivasan' left right node4349498088:c->node4349497976 node4349498032 Tree value 'april' left right node4349498088:c->node4349498032 node4349498200 Tree value 'mike' left right node4349498256:c->node4349498200

In [24]:
from IPython.display import display

N = 100

def f(x):
    a = ['hi','mom']
    thestack = callsviz(varnames=['table','x','head','courses','N','a'])
    display(thestack)
    
f(99)


G cluster1 node140525388275848 globals N 100 table     head     a     courses     node140525388282824 f x 99 a     node4349426544 Node value 'xue' next     node140525388275848:c->node4349426544 node4348961288 0 1 2 3 4 node140525388275848:c->node4348961288 node4349409320 set node140525388275848:c->node4349409320 node4348961736 0 1 2 node140525388275848:c->node4348961736 node4348963016 0 1 'hi' 'mom' node140525388282824:c->node4348963016 node4349426432 Node value 'tombu' next     node4349426656 Node value 'parrt' next     node4349426656:c->node4349426432 node4349426544:c->node4349426656 node4348963272 empty list node4348961288:0->node4348963272:w node4348556168 empty list node4348961288:1->node4348556168:w node4349345160 0 1 node4348961288:2->node4349345160:w node4349343816 empty list node4348961288:3->node4349343816:w node4349263688 empty list node4348961288:4->node4349263688:w node4347390088 0 1 'a' 99 node4349345160:0->node4347390088:w node4347404104 0 1 'f' 99 node4349345160:1->node4347404104:w node4349425816 Node value 'parrt' next     node4349409320:0->node4349425816:w node4349423912 Node value 'mary' next     node4349409320:1->node4349423912:w node4347682696 0 1 'msan501' 51 node4348961736:0->node4347682696:w node4349436232 0 1 'msan502' 32 node4348961736:1->node4349436232:w node4349343880 0 1 'msan692' 101 node4348961736:2->node4349343880:w

If you'd like to save an image from jupyter, use render():


In [25]:
def f(x):
    thestack = callsviz(varnames=['table','x','tree','head','courses'])
    print(thestack.source[:100])  # show first 100 char of graphviz syntax
    thestack.render("/tmp/t") # save as PDF
    
f(99)


    digraph G {
        nodesep=.1;
        ranksep=.1;
        rankdir=LR;
        node [penwidth=

Numpy viz


In [26]:
import numpy as np

A = np.array([[1,2,8,9],[3,4,22,1]])
objviz(A)


Out[26]:
G node4349247360 1 2 8 9 3 4 22 1

In [27]:
B = np.ones((100,100))
for i in range(100):
    for j in range(100):
        B[i,j] = i+j
B


Out[27]:
array([[  0.,   1.,   2., ...,  97.,  98.,  99.],
       [  1.,   2.,   3., ...,  98.,  99., 100.],
       [  2.,   3.,   4., ...,  99., 100., 101.],
       ...,
       [ 97.,  98.,  99., ..., 194., 195., 196.],
       [ 98.,  99., 100., ..., 195., 196., 197.],
       [ 99., 100., 101., ..., 196., 197., 198.]])

In [28]:
matrixviz(A)


Out[28]:
G node4349247360 1 2 8 9 3 4 22 1

In [29]:
matrixviz(B)


Out[29]:
G node4369386992 0. 1. 2. 3. 4. ... 95. 96. 97. 98. 99. 1. 2. 3. 4. 5. ... 96. 97. 98. 99. 100. 2. 3. 4. 5. 6. ... 97. 98. 99. 100. 101. 3. 4. 5. 6. 7. ... 98. 99. 100. 101. 102. 4. 5. 6. 7. 8. ... 99. 100. 101. 102. 103. 95. 96. 97. 98. 99. ... 190. 191. 192. 193. 194. 96. 97. 98. 99. 100. ... 191. 192. 193. 194. 195. 97. 98. 99. 100. 101. ... 192. 193. 194. 195. 196. 98. 99. 100. 101. 102. ... 193. 194. 195. 196. 197. 99. 100. 101. 102. 103. ... 194. 195. 196. 197. 198.

In [30]:
A = np.array(np.arange(-5.0,5.0,2.1))

B = A.reshape(-1,1)

matrices = [A,B]

def f():
    w,h = 20,20
    C = np.ones((w,h), dtype=int)
    for i in range(w):
        for j in range(h):
            C[i,j] = i+j
    display(callsviz(varnames=['matrices','A','C']))

f()


G node4369510472 globals A     matrices     node4365545544 f C     node4369449328 -5. -2.9 -0.8 1.3 3.4 node4369510472:c->node4369449328 node4369322952 0 1 node4369510472:c->node4369322952 node4369449408 0 1 2 3 4 ... 15 16 17 18 19 1 2 3 4 5 ... 16 17 18 19 20 2 3 4 5 6 ... 17 18 19 20 21 3 4 5 6 7 ... 18 19 20 21 22 4 5 6 7 8 ... 19 20 21 22 23 15 16 17 18 19 ... 30 31 32 33 34 16 17 18 19 20 ... 31 32 33 34 35 17 18 19 20 21 ... 32 33 34 35 36 18 19 20 21 22 ... 33 34 35 36 37 19 20 21 22 23 ... 34 35 36 37 38 node4365545544:c->node4369449408 node4369322952:0->node4369449328:w node4349247360 -5. -2.9 -0.8 1.3 3.4 node4369322952:1->node4349247360:w

Pandas dataframes, series


In [31]:
import pandas as pd
df = pd.DataFrame()
df["sqfeet"] = [750, 800, 850, 900,950]
df["rent"] = [1160, 1200, 1280, 1450,2000]
objviz(df)


Out[31]:
G node4369498008 750 1160 800 1200 850 1280 900 1450 950 2000

In [32]:
objviz(df.rent)


Out[32]:
G node4369537008 1160 1200 1280 1450 2000