After a first attempt of drawing a connectome (map of neural connections in the brain), I came up with a more ambitious idea for a visualization. Draw one and each of the lines in the square matrix. We are talking about an average of ±80.000 lines. Bokeh seemed to be performant enough in the last visualization I made, with this one, we will see where the actual limits are.
If not dots, then what ?
Arcs, arcs is the answer to that question. If we know the number of connections in a region we can figure out the percent that each area represents in the length of a circumference; creating each area as an arc scaled with that length, the sum will be a complete circle.
An arc in Bokeh is a glyph and to be drawn needs:
'x', 'y', 'radius', 'start_angle', 'end_angle' and
'direction'. X and Y are the center of my circle (0,0) and the radius will be 1 to make things easier. The missing values are
end_angle ; with them we will be able to draw the arcs and the circumference.
Loading the info
To know the length that each area should have, we need first of all to know the number of connections that each area has.
Now that we know the number of connections per area, we can know the length that it would represent in a circunference. For that, I will use radians and radius = 1 to make operations easier.
If this is this operation was correct, the sum should be near a 2π radians.
An arc of a circle is a “portion” of the circumference of the circle. The length of an arc is simply the length of its “portion” of the circumference. Now that we now the length of each area in a circumference we need to know the start and end angles of the arc in order to be able to draw them. The radian measure,
ø, of a central angle of a circle is defined as the ratio of the length of the arc the angle subtends,
s, divided by the radius of the circle,
So in this case
ø = s makes everything much easier. Our points must start on zero, so I add a zero in the begining of the array.
Let’s add some color using the function we already created for the previous connectome.
Creating the arcs
The easiest way is to create a ColumnDataSource instance with the data we need to create the arcs in order to reuse this same instance later on.
We configure the plot
And print it !
I got those arcs, now what ?
bokeh.crazy_scientific_mode = True
Now let’s get into the real stuff. Drawing so many lines is not an easy task, so I did it using OOP to make it more understandable. I’m sure there is someone reading this and thinking, “meh, I can do that without declaring a class” for those; please, do it and share your approach.
We can create each area as an arc with it’s start and end point and the number of connections there should be in that area.
Now we generate each of the areas in the connectome as an object and store them in a list.
Each of those areas we just created has all the points(x,y) that the connections will start from or go to. Those points are in the same space than the arcs we defined earlier. That will create the illusion that the lines are created from the arc, as they will share the same color that the arc they were started from.
Now we have to create each of those lines. The easiest thing is just to loop through all the areas and create each connection.
4740 connections in total that we will draw in the plot. Let’s store them in a DataFrame to easily create a ColumnDataSource later on.
I store the values in the DataFrame as strings to store as many precission as possible. I found that storing them as floats, made me lose lot of precission and bokeh is taking the string values without problems.
Now we create the curves and add them to the DataFrame
We standarize the weights and give them a value that will make them visible. With this, the most important areas will be much more opaque than those with less number of connections.
Once again, using ColumnDataSource I store all the data from the pandas DataFrame in a bokeh compatible object
Aaaaaaand let’s plot it
Add the glyphs to the plot…
<bokeh.models.renderers.GlyphRenderer at 0x111a7da58>
And Voilá !
Sadly, taking all the connections would make your browser process tooooooo much info when generating the visualization. What you see here is just a rendering of the
connectome[:40][:40] You can try the full visualization with the jupyter notebook but use at your own risk ;)
Cool, but some things are still missing…
This is a work in progress, working on this visualization I found several limitations in Bokeh.
- Add WebGL support for arcs and beziers
- Add HoverTool to arcs to display information on the areas
- Add TapTool to arcs to be able to display only the connections originated from one area
- Create a bokeh interface for Chord graphs
I hope that with my time and the help of the community we can get these working. That would give you the ability Chord graphs just by passing an square matrix. My hope is that in the next several months we can see this integrated inside Bokeh.
Thanks for passing by, you can download all the code HERE!