Thursday, December 22, 2016

Visualize your ideas using Rasem

A major part of a researchers' work is to write papers and articles that describe their work and make posters and presentations to better communicate their ideas. We all believe that "A picture is worth a thousand words" and we are always looking for better ways to visualize our ideas. In this blog article, I present Rasem, a library that I built as I started my PhD and used it in many of my papers and presentation to build nice visualizations like the ones shown below.

The figures shown above are generated from hundreds or thousands of records and are formatted based on some logic related to the algorithm being illustrated in the relevant papers. Furthermore, although not shown in this blog article, these figures are vector images which would be very nice to include in articles that will be printed. These two features, i.e., thousands of elements and user-defined logic, make it impractical to draw these figures manually using any image editor such as Inkscape. This blog article describes a simple tool that makes it very easy to generate all these figures.

Overview and Usage

Rasem uses Ruby code to describe images and generates standard SVG images that can be further edited or converted to EPS or PDF by popular applications including the open source Inkscape and Adobe Illustrator. Even if you're not a ruby developer, you can easily use Rasem as it's very simple to use.

A simple example

The contents of the file are self explanatory. Now to generate an image out of this figure, all you need to do is to type the following command.

rasem test.rasem

or simply type

rasem

It will generate an SVG file named 'test.svg' which you can simply display in your Internet browser and is shown below.

You can find more examples at https://github.com/aseldawy/rasem
The best feature of Rasem is that the file shown above is a fully functioning Ruby code. Which means you can include additional Ruby constructs and integrate it seamlessly with the visualized image. This is further shown in the following example which visualizes a simple graph.

How it works

Rasem relies on the dynamic features of Ruby which allows it to compile and run user-defined code on-the-fly. The line and circle commands shown above are nothing but function calls which are part of the API of Rasem. There are more functions in Rasem including rectangle, polygon, and polyline. These functions generate XML elements that conform to the SVG standard to draw the corresponding elements. That's how you can easily integrate your Ruby code into your figure to add user-defined logic which can affect both the generated figure elements and their style. You can also write a code that opens an external file, parses it, and generates the figure from this data. Rasem is open source and you're welcome to use it or contribute to it.

A Voronoi Diagram example

In this part, we show a more sophisticated example that we used to draw a Voronoi Diagram figure similar to the one shown below. We describe some tricks that can be used to generate similar figures.

The input file was generated using the Voronoi diagram operation in SpatialHadoop and it looks like the following snippet.
189.05078396875297,319.3714811786753 POLYGON ((194.43089260205164 325.5334210386081, 170.08384007573167 321.1403988020476, 198.24373337246874 315.0171135767282, 194.43089260205164 325.5334210386081))
3.678985871399587,429.815627730571 LINESTRING (-46.06193792012205 322.23283446689334, -46.06193792012205 322.23283446689334)
Each line has X and Y coordinates for the site followed by a WKT representation of a POLYGON or a LINESTRING that represents a closed or an open Voronoi region, respectively.
We start by providing the code that reads and parses those lines.

Now, let's make it more interesting. We would like to give different colors, as shown above, for safe and unsafe regions as described in the SpatialHadoop Voronoi diagram blog post. We define the following function that decides whether a site is safe or not.

We can now easily make a test before drawing each region to decide the color we use to draw each region. However, as a part of this tutorial we will do it in a different way. Instead of applying the styles in the Rasem code, we will apply them in Inkscape. We will use Rasem only to separate safe and unsafe regions. We will use the "group" feature in Rasem and SVG to put each set of regions together as shown in the following code.

def draw_vd(in_file, out_file, mbr)
outs = File.open(out_file, "w")
mbr_width = mbr[2] - mbr[0]
mbr_height = mbr[3] - mbr[1]
regions = read_regions(in_file)
Rasem::SVGImage.new({:width=>mbr_width, :height => mbr_height}, outs) do
rectangle mbr[0], mbr[1], mbr_width, mbr_height, :stroke=>"black", :fill=>:none
# Group 1: Safe regions
group do
# Sub-group 1: Points
group do
for region in regions
if is_safe(region, mbr)
circle region[:x], region[:y], 1
end
end
end
# Sub-group 2: Regions
group(:fill => :none) do
for region in regions
if is_safe(region, mbr)
draw_region svg, region
end
end
end
end
# Group 2: non-safe regions
group do
# Sub-group 1: Points
group do
for region in regions
if !is_safe(region, mbr)
circle region[:x], region[:y], 1
end
end
end
# Sub-group 2: Regions
group(:fill => :none) do
for region in regions
if !is_safe(region, mbr)
draw_region svg, region
end
end
end
end
end
#svg.write(outs)
outs.close
end

The code is much longer than before but it is very simple. We create two big groups for safe and unsafe regions. Then, we create two subgroups within each one for sites and regions. This makes a total of four subgroups, namely, safe sites, safe regions, unsafe sites, and unsafe regions. This makes it easier to select apply a style to each individual group in Inkscape. This technique is preferable than applying the styles in the code because you can easily choose the most appealing colors in a GUI and get an instant feedback on your choice rather than modifying the code and regenerating the image.

Exporting standard SVG images is a very powerful feature in Rasem as it allows users to further edit the generated images in their favorite image editor such as Inkscape or Adobe Illustrator. This way, you can easily integrate different figures together, add some text, or some other annotations.