Take Full Control of Your Python Plots with Jinja
By: Austin Poor
Tags: Python, Jinja, Data Science, SVG, Data Visualization

Take Full Control of Your Python Plots with Jinja

Create fully custom plots in Python with SVG and Jinja

Photo by Isaac Smith on Unsplash

Have you ever spent way too long digging through documentation, trying to get your plots to look the way you want? Next time it happens, consider ditching matplotlib or seaborn and using Jinja to create a custom plot.

Jinja is a Python templating language, based on Django templates, which you may be familiar with from other packages like Flask or Airflow. It has a ton of useful features but you only need some basics to get started.

You can use Jinja to make your visual as an SVG (with a workflow that’s pretty similar to D3’s) and display them, all while staying in Jupyter.

Some Basic SVG

Before we get into the big stuff, let me cover some basics. SVG stands for Scalable Vector Graphics, meaning all the image data is stored as points in vector space and therefore can be resized without getting pixelated (unlike raster images).

SVGs are XML-based and have many different tags, representing different paths and shapes. Some key tags are:

circle : Draws a circle using xy coordinates and a radius

: Draws a circle using xy coordinates and a radius rect : Draws a rectangle using xy coordinates for upper-left corner plus width and height

: Draws a rectangle using xy coordinates for upper-left corner plus width and height polyline : Draws a path of connected xy points

: Draws a path of connected xy points text : Draws text

Each SVG element has its own attributes that can be changed but most elements share common attributes to control the fill and stroke.

One other key thing to keep in mind when creating SVGs is that the xy coordinates start at (0,0) in the upper-left corner and increase as they move towards the bottom-right corner.

For more information on working with SVGs check out Mozilla’s reference material here.

Now on to Jinja…

A (Mini) Intro to Jinja Templates

Jinja’s templates have great features like loops, conditionals, and template inheritance, and that’s just scratching the surface; there is a ton of functionality.

Here’s a basic example of a Jinja template:

{% for name in names %}

Hello, {{ name }}, welcome to {{ place }}!

{% endfor %}

And if you were to render the template with names = ["tim", "sue", "tom", "sally"] and place = "my party" , you’d get…

Hello, tim, welcome to my party!

Hello, sue, welcome to my party!

Hello, tom, welcome to my party!

Hello, sally, welcome to my party!

For more information on Jinja templates, check out the docs.

Now, let’s move on to building a plot with Jinja.

Plotting with Jinja

Let’s make a simple demo scatter plot with some example data, using Jinja.

For starters, here’s the data and some basic layout info I’ll use in my template:

Data and layout information for making the plot.

Now let’s make the template, which will be a mix of SVG’s XML-style tags and special Jinja commands:

Let’s assume our template is stored as a string in the variable plot_template .

Now we can render the template, using our plot and layout data, with the following code:

And here’s what the rendered plot would look like as an svg:

And here it is as a png for reference:

SVG demo plot created in Python using Jinja

For the complete code, check out the gist here.

Conclusion

If you’re just doing EDA calling plt.scatter(x,y) is still the way to go, but if you want to be able to fully customize your plot try using Jinja. It might take more time to start up but your templates are easily reusable and you aren’t limited to the plots that are supported by your plotting library.

Another great benefit of SVGs is the ability to copy the path from another SVG and incorporate it into your own. For example, if you wanted to change the points in your scatter plot to be your company’s logo and your competitors, all you need to do is download the SVG logos and replace the circles in your template with the logo paths.

Thanks for reading! I’d love to know what you think of this technique — let me know if you have any comments or suggestions!