Radial convergence diagram (aka chord diagram) for sensitivity analysis results and other inter-relationships between data

TLDR; Python script for radial convergence plots that can be found here.

You might have encountered this type of graph before, they’re usually used to present relationships between different entities/parameters/factors and they typically look like this:

From https://datavizcatalogue.com/methods/non_ribbon_chord_diagram.html

In the context of our work, I have seen them used to present sensitivity analysis results, where we are interested in both the individual significance of a model parameter, but also the extent of its interaction with others. For example, in Butler et al. (2014) they were used to present First, Second, and Total order parameter sensitivities as produced by a Sobol’ Sensitivity Analysis.

From Butler et al. (2014)

I set out to write a Python script to replicate them. Calvin Whealton has written a similar script in R, and the same functionality also exists within Rhodium. I just wanted something with a bit more flexibility, so I wrote this script that produces two types of these graphs, one with straight lines and one with curved (which are prettier IMO). The script takes dictionary items as inputs, either directly from SALib and Rhodium (if you are using it to display Sobol results), or by importing them (to display anything else). You’ll need one package to get this to run: NetworkX. It facilitates the organization of the nodes in a circle and it’s generally a very stable and useful package to have.

Graph with straight lines
Graph with curved lines

I made these graphs to display results the results of a Sobol analysis I performed on the model parameters of a system I am studying (a, b, c, d, h, K, m, sigmax, and sigmay). The node size indicates the first order index (S1) per parameter, the node border thickness indicates the total order index (ST) per parameter, and the thickness of the line between two nodes indicates the secord order index (S2). The colors, thicknesses, and sizes can be easily changed to fit your needs. The script for these can be found here, and I will briefly discuss what it does below.

After loading the necessary packages (networkx, numpy, itertools, and matplotlib) and data, there is some setting parameters that can be adapted for the figure generation. First, we can define a significance value for the indices (here set to 0.01). To keep all values just set it to 0. Then we have some stylistic variables that basically define the thicknesses and sizes for the lines and nodes. They can be changed to get the look of the graph to your liking.

# Set min index value, for the effects to be considered significant
index_significance_value = 0.01
node_size_min = 15 # Max and min node size
node_size_max = 30
border_size_min = 1 # Max and min node border thickness
border_size_max = 8
edge_width_min = 1 # Max and min edge thickness
edge_width_max = 10
edge_distance_min = 0.1 # Max and min distance of the edge from the center of the circle
edge_distance_max = 0.6 # Only applicable to the curved edges

The rest of the code should just do the work for you. It basically does the following:

  • Define basic variables and functions that help draw circles and curves, get angles and distances between points
  • Set up graph with all parameters as nodes and draw all second order (S2) indices as lines (edges in the network) connecting the nodes. For every S2 index, we need a Source parameter, a Target parameter, and the Weight of the line, given by the S2 index itself. If you’re using this script for other data, different information can fit into the line thickness, or they could all be the same.
  • Draw nodes and lines in a circular shape and adjust node sizes, borders, and line thicknesses to show the relative importance/weight. Also, annotate text labels on each node and adjust their location accordingly. This produces the graph with the straight lines.
  • For the graph with the curved lines, define function that will generate the x and y coordinates for them, and then plot using matplotlib.

I would like to mention this script by Enrico Ubaldi, based on which I developed mine.

Embedding figure text into a Latex document

Often times we have to create plots and schematic drawings for our publications. These figures are then included in the final document either as bitmaps (png, jpeg, bmp) or as vectorized images (ps, eps, pdf). Some inconveniences that arise due to this process and are noticed in the final document are:

  • Loss of image quality due to resizing the figure (bitmaps only)
  • Different font type and size from the rest of the text
  • Limited resizing possibility due to text readability
  • No straight-forward method to add equations to the figure

If the document is being created in LaTeX, it is possible to overcome all these inconveniences by exporting your figure into either svg or postscript formats and converting it into pdf+Latex format with Inkscape. This format allows the LaTeX engine to understand and treat figure text as any other text in the document and the lines and curves as a vectorized image.


The process for creating of a PDF+LaTeX figure is described below:

1 – Create your figure and save it in either svg or postscript format. Inkscape, Matlab, GNUPlot, and Python are examples of software that can export at least one of these formats. If your figure has any equations, remember to type them in LaTeX format in the figure.

2 – Open your figure with Inkscape, edit it as you see necessary (figure may need to be ungrouped), and save it.

3.0 – If you are comfortable with using a terminal and the figure does not need editing, open a terminal pointing to the folder where the figure is and type the following the command (no $). If this works, you can skip steps 3 and 4 and go straight to step 5.

$ inkscape fig1.svg --export-pdf fig1.pdf --export-latex

3 – Click on File -> Save As…, select “Portable Document Format (*.pdf)” as the file format, and click on Save.


4 – On the Portable Document Format window that will open, check the option “PDF+LaTeX: Omit text in PDF, and create LaTeX file” and click on OK.


Inkscape will then export two files, both with the same name but one with pdf and the other with pdf_tex extension. The pdf file contains all the drawing, while the pdf_tex contains all the text of the figure and calls the pdf file.

5 – On your latex document, include package graphicx with the command \usepackage{graphicx}.

6 – To include the figure in your document, use \input{your_figure.pdf_tex}. Do not use the conventional \includegraphics command otherwise you will end up with an error or with a figure with no text. If you want to scale the figure, type \def\svgwidth{240bp} (240 is the size of your figure in pixels) in the line before the \input command. Do not use the conventional [scale=0.5] command, which would cause an error. Some instructions are available at the first lines of the pdf_tex file, which can be opened with a regular text editor such as notepad.

Below is a comparison of how the same figure would look like in the document if exported in PDF+LaTeX and png formats. It can be seen that the figure created following the procedure above looks smoother and its text style matches that of the paragraphs above and below, which is more pleasant to the eyes. Also, the text can be marked and searched with any pdf viewer. However, the user should be aware that, since text font size is not affected by the scaling of the figure, some text may end up bigger than boxes that are supposed to contain it, as well as too close or to far from lines and curves. The former can be clearly seen in the figure below. This, however, can be easily fixed with software such as Inkscape and/or with the editing tips described in the following section.



If you noticed a typo of a poorly positioned text in the figure after the figure has been exported and inserted in your document, there is a easier way of fixing it other than exporting the figure again. If you open the pdf_tex file (your_figure.pdf_tex) with a text editor such as notepad, you can change any text and its position by changing the parameters of the \put commands inside the \begin{picture}\end{picture} LaTeX environment.

For example, it would be better if the value 1 in the y and x axes of the figures above would show as 1.0, so that its precision is consistent with that of the other values. The same applies to 2 vs. 2.0 in the x axis. This can be fixed by opening file fig1.pdf_tex and replacing lines:




Also, one may think that the labels of both axes are too close to the axes. This can be fixed by replacing lines:

\put(0.02933333,0.434){\rotatebox{90}{\makebox(0,0)[b]{\smash{$x\cdot e^{-x+1}$}}}}%


\put(0.0,0.434){\rotatebox{90}{\makebox(0,0)[b]{\smash{$x\cdot e^{-x+1}$}}}}%

With the modifications described above and resizing the legend box with Inkscape, the figure now would look like this:


Don’t forget to explore all the editing features of inkscape. If you export a figure form GNUPlot or Matlab and ungroup it with Inkscape into small pieces, Inkscape would give you freedom to rearrange and fine tune your plot.

Converting an SVG to EPS


Encapsulated PostScript (EPS) is the standard graphics format for many journals.   Having just converted my figures to EPS, I want to share what I’ve learned.  The short version: while at first the results look dreadful, with a little work, Scalable Vector Graphics (SVG) images can be converted into decent looking EPS files.

The reason you might have SVG figures in the first place is that you are using Inkscape rather than Adobe Illustrator (AI) to develop them. Unlike AI, Inkscape is unencumbered by Adobe software licensing restrictions, and you can use it on any mainstream operating system.  It uses SVG format to store vector images, so if you are developing figures in Inkscape, you will eventually need to convert them to EPS format. For AI, this is less of a problem, because AI format is apparently a close cousin to EPS.

Variations on a Naïve Approach

The naïve approach is to export an EPS figure directly from Inkscape.  For all but the simplest images, this doesn’t work. The result of this export is an image that mixes vector and rasterized components seemingly at random.  This produces truly bizarre and ugly results.  Some variations on the naïve approach that work equally well are: opening the SVG in Illustrator, copying and pasting from Inkscape to Illustrator, and saving as a Windows Metafile to open in Illustrator.  To be clear, none of these variations produces remotely good results.

Why the Naïve Approach Fails

The naïve approach fails because EPS is not a very sophisticated file format.  In particular, it has very poor support for transparency.  Whenever I had a figure that used alpha at all, which is almost every figure, the EPS export turned out badly.  This page on Adobe’s website seems to indicate that Illustrator does some proprietary magic to get decent transparency in EPS files.  Whatever it is, Inkscape doesn’t do it, and I couldn’t find an automatic converter that did.  In addition to Inkscape’s SVG to EPS converter, I tried ImageMagick and Scribus, neither of which did any better, and both of which found new ways to fail.

Rasterization (No! Not Rasterization!)

“No! Not rasterization!” was my first response when I realized that rasterization is by far the easiest way out.  Rasterization is ugly.  It gives you aliased lines and blurry fonts.  And EPS is at least nominally a vector format, so rasterization is particularly painful because it ought not to be necessary. Here’s the obligatory illustration of how ugly rasterized text can be:

Rasterized version of the letter A

Rasterization is ugly!

Also, rasterization gives you huge files!  Here’s how EPS represents vector content:

4 M q 1 0 0 -0.477488 0 275.015381 cm
359.477 352.537 m 322.563 388.606 263.395 387.919 227.324 351.007 c 
191.254 314.087 191.941 254.923 228.855 218.854 c 265.77 182.785 
324.938 183.472 361.008 220.384 c 394.121 254.277 396.633 307.583 
366.848 344.438 c S Q
363.973 108.851 m 365.199 112.59 l 371.363 110.211 l h
363.973 108.851 m f*
0.77053 w
q -0.808223 -0.477488 -1 0.385917 0 275.015381 cm
32.558 -390.287 m 27.223 -387.201 l 27.223 -393.365 l h
32.558 -390.287 m S Q
1.368923 w
1 J
q 1 0 0 -1 0 275.015381 cm
281.66 33.609 m 272.492 27.789 270.355 16.457 276.895 8.297 c 283.43

I don’t know EPS at all; this is just a sample of vector graphics look like in an EPS file.  I’m pretty sure those are drawing commands.  Anyway, compare with raster graphics:


Unlike the vector commands, I can tell you exactly what’s going on there, and it’s not pretty.  Those are 8 bit RGB values in hexadecimal, represented with ASCII text (which means that they take up exactly twice as much space as they need to.)  So one light grey pixel is, for example, ADADAD.  And all those Fs?  Empty white space.  This is why high resolution bitmaps take up a ridiculous amount of space in EPS format.

So much for the case against rasterization.  The case for it is simply that the alternative is much more work..

How to Rasterize an SVG

First, in Inkscape, make a new layer for your background.  Put a big white rectangle in it, and lower this layer to the bottom of the layer stack.  This step prevents the background from being filled in unpredictably.

Inkscape can export directly to raster formats.  As I mentioned, it also exports to EPS, but that naïve route doesn’t work.  Export your figure as a Portable Network Graphics (PNG) file.  Use an embarrassingly large resolution.  This is just an intermediate step, and you can always delete the PNG once you have your EPS.  The PNG is compressed, so it will take up much less space than the EPS anyway. Next comes the part where you need another piece of free software.  Get a copy of ImageMagick.  Then use its convert utility to make an EPS from the PNG.  For example,

convert -resize 50% simplex_schematic.png simplex_schematic.eps

Play around with the percentage by which you resize the figure. Be happy that in this modern era, nobody bats an eye at a four megabyte image file.

A Hybrid Approach

By understanding its limitations, we can make Inkscape’s EPS export work for us.  Remember how I said Inkscape’s rasterization is unpredictable?  We can make it more predictable by rasterizing part of the figure.  If enough of the figure is already rasterized, Inkscape will leave the rest in vector form.  My theory on what gets rasterized is as follows.  Any vector content that has a property that EPS can’t handle, particularly transparency, gets rasterized.  Also, any vector content that interacts with a property EPS can’t handle.  So if you have text under a transparent overly, all of it gets rasterized, even if the text itself is opaque.

The basic hybrid approach is to separate all text in your figure into a separate layer, hide the text layer, and export the rest of the figure as a high-resolution bitmap.  Then import the bitmap, line it up with the vector components it replaces, and hide the vector components of the figure other than text, so you have text overlaid on an opaque raster image.  Finally export as an EPS.  These actions improve the appearance of the figure considerably, since rasterized text looks dreadful.

This approach can be extended to non-text elements of your figure, if you have the patience for it.  This works best for simple elements like arrows and axes, as long as they don’t have anything drawn over them.  The point of diminishing returns arrives rapidly, however.


Inkscape is great. It’s free, and it’s easy to use. If, during the figure creation process, you’re careful about segregating the parts of your figure that force rasterization, you can enjoy the clean lines of vector graphics in your finished figure. Even if you don’t consider the EPS conversion until very late, picking the low-hanging fruit (text) is easy and dramatically improves the appearence of your figure.

Edit (4 February, 2013): A better explanation

See these threads on StackExchange: