Quick (and dirty ?) way to make annotable plots for collaborators, possibly using webagg?


I want to share plots with collaborators in a way that makes it possible for them to annotate certain points. The very basic way to do it would be to just save images, put it in a powerpoint file, and let them add arrows and text boxes to it. This would work but I am wondering if something a little more elegant could be easily done…

I discovered the webagg backend, which seems to work pretty well for the kind of plot I need. But not being a web-developper at all, I wanted to ask a few questions here before burying myself too deep with problems that are very far from my field of expertise.

  • Is there another tool more suited for this task?
  • Is there more documentation for this backend somewhere?
  • Is it easy to make clickable plots with the webagg backend? Something like handling clicks on the canvas, and adding a text annotation to it.
  • Is there a way to produce static html+js files? The annotations results could then be saved to a file; every would be done browser-side?
  • Is it possible to put the tornado server behind a reverse proxy? I tried this nginx config [1] but to serve the only example I could find but to no avail. My goal would be to add a minimum layer of security in case I serve the files from my computer. I works fine by directly accessing localhost:8080.

Thanks for reading time, I hope I followed guidelines for this first post.


– Nicolas


server {
    server_name    webagg.mydomain.tld;

    location / {
        auth_basic "Show me your credentials";
        auth_basic_user_file /etc/nginx/anhtpasswdfile;
        proxy_pass        http://localhost:8080/;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_buffering off;

    # shameless attempt to copy jellyfin websocket setteing settings

    location /ws {
        proxy_pass        http://localhost:8080/;;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;


To answer your questions in order:

  • I’m not qualified to answer
  • On a practical level https://matplotlib.org/gallery/user_interfaces/embedding_webagg_sgskip.html is a good reference for how to embed it in a full webpage.
  • Yes, on the Matplotlib side it is exactly the same as the desktop/GUI backends See https://matplotlib.org/users/event_handling.html for how to get callbacks when the user interacts with your figure.
  • webagg requires a server to run the python side. It is possible to template a page with a static rendering (as svg or png) after the annotation is done.
  • It should be possible, but you will need to proxy the websocket connections as well as the http

Hope that helps!

1 Like

Thank you very much for your answer. The lack of documentation and my lack of webdev knowledge made me go for dash instead.

Glad you found a solution but if you find yourself needing Matplotlib again, panel is a multi-library dashboarding tool.