Solved – Libraries for forest and funnel plots

data visualizationfunnel-plotjava

Can anyone recommend me an open source graphic library to create forest and funnel plots?

I was aiming at using it on a Java desktop application.

Best Answer

Well, i use graphviz, which has Java bindings (Grappa).

Although the dot language (graphviz's syntax) is simple, i prefer to use graphviz as a library through the excellent and production-stable python bindings, pygraphviz, and networkx.

Here's the code for a simple 'funnel diagram' using those tools; it's not the most elaborate diagram, but it is complete--it initializes the graph object, creates all of the necessary components, styles them, renders the graph, and writes it to file.

import networkx as NX
import pygraphviz as PV

G = PV.AGraph(strict=False, directed=True)     # initialize graph object

# create graph components:
node_list = ["Step1", "Step2", "Step3", "Step4"]
edge_list = [("Step1, Step2"), ("Step2", "Step3"), ("Step3", "Step4")]
G.add_nodes_from(node_list)
G.add_edge("Step1", "Step2")
G.add_edge("Step2", "Step3")
G.add_edge("Step3", "Step4")

# style them:
nak = "fontname fontsize fontcolor shape style fill color size".split()
nav = "Arial 11 white invtrapezium filled cornflowerblue cornflowerblue 1.4".split()
nas = dict(zip(nak, nav))
for k, v in nas.iteritems() :
    G.node_attr[k] = v

eak = "fontname fontsize fontcolor dir arrowhead arrowsize arrowtail".split()
eav = "Arial 10 red4 forward normal 0.8 inv".split()
eas = dict(zip(eak, eav))
for k, v in eas.iteritems() :
    G.edge_attr[k] = v

n1 = G.get_node("Step1")
n1.attr['fontsize'] = '11'
n1.attr['fontcolor'] = 'red4'
n1.attr['label'] = '1411'
n1.attr['shape'] = 'rectangle'
n1.attr['width'] = '1.4'
n1.attr['height'] = '0.05'
n1.attr['color'] = 'firebrick4'
n4 = G.get_node("Step4")
n4.attr['shape'] = 'rectangle'

# it's simple to scale graph features to indicate 'flow' conditions, e.g., scale 
# each container size based on how many items each holds in a given time snapshot:
# (instead of setting node attribute ('width') to a static quantity, you would
# just bind 'n1.attr['width']' to a variable such as 'total_from_container_1'

n1 = G.get_node("Step2")
n1.attr['width'] = '2.4'

# likewise, you can do the same with edgewidth (i.e., make the arrow thicker
# to indicate higher 'flow rate')

e1 = G.get_edge("Step1", "Step2")
e1.attr['label'] = '  1411'
e1.attr['penwidth'] = 2.6

# and you can easily add labels to the nodes and edges to indicate e.g., quantities: 
e1 = G.get_edge("Step2", "Step3")
e1.attr['label'] = '  392'

G.write("conv_fnl.dot")      # save the dot file
G.draw("conv_fnl.png")       # save the rendered diagram

alt text http://a.imageshack.us/img148/390/convfunnel.png

Related Question