Custom Visualization in Julia

One of the things I love about Julia is how easy it is to plug into a larger ecosystem of prepackaged functionality.

One of these things is the system for representing and displaying objects in Julia. Your custom data types will get a sensible display in the Julia REPL environment by default, but you can override this default and create a custom representation.

Most of the times this will just be another textual representation. However you can view objects as drawings. In this simple example we'll take a humble vector type we have defined ourselves called Vec2D and give it a graphical representation.

struct Vec2D
  x::Float64
  y::Float64
end
0.3s

To do that we need to import the show function from the Julia Base module. In Julia speak this is so we can add a method to the function. Yes for you object-oriented guys this is odd terminology, but in Julia you don't add methods to classes (there are no classes in Julia), you add methods to functions.

A function has different methods to handle different number of arguments and different argument types. In our case we want to add a method to show, which handle cases where the second argument is of MIME type SVG (scalable vector graphics), and the third argument is our new custom Vec2D type.

import Base: show
function show(io::IO, ::MIME"image/svg+xml", v::Vec2D)
    width = 500
    height = 200
    x1 = width/2
    y1 = height/2
    x2 = v.x*50 + x1
    y2 = v.y*25 + y1
    s = """
    <svg version="1.1"
       baseProfile="full"
       width="$width" height="$height"
       xmlns="http://www.w3.org/2000/svg">
       <defs>
         <marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
           <path d="M0,0 L0,6 L9,3 z" fill="#aaa" />
         </marker>
       </defs>
       <line x1="$x1" y1="$y1" x2="$x2" y2="$y2" stroke="#aaa" stroke-width="5" marker-end="url(#arrow)" />
    </svg>
    """
    print(io, s)
end
0.6s
show (generic function with 218 methods)

This method will return a textual SVG representation of this type. If you are in an environment which supports display of SVG then the object will be drawn when evaluated.

v = Vec2D(-2, 2)
0.3s

That is what you see above. We evaluated the v vector, and Nextjournal knows how to display SVG object. Where else do you wonder? Well Juno also supports it, while e.g. command line REPL in your Unix terminal would not support it.

Not out of the box anyway. You would have to add by yourself or through some package a subtype of AbstractDisplay which handles SVG.

Runtimes (1)