Looking for a program to draw scientific sketches

Does someone know a free program with which i can draw high quality figures for my scientific thesis. I want to draw similar figures like this example

Picture is from: E. Lucon Oscillateurs coupl ́es, d ́esordre et

Python + Matplotlib (possibly used from within Jupyter Notebooks) can generate that sort of diagram at publication quality and in publication suitable formats, all for free and on multiple platforms.

Some Example Code

As starting point, it's not perfect, but you should be able to get the idea:

Cell 1

%matplotlib inline


Cell 2

import matplotlib.pyplot as plt
from matplotlib.patches import Arc, Arrow
import numpy as np
import itertools


Cell 3

def get_circle(x, y, r=1):
""" Get a cirlce with a specific position and radius"""
result = plt.Circle((x, y), r, color='k', fill=False)
return result

def rpoint(x, y, r, deg):
""" Get a point on a radius at deg degrees."""
x1 = x + r * np.sin(rang)
y1 = y + r * np.cos(rang)
return (x1, y1)

def radial(x, y, r=1, ang=0, style="-"):
""" Draw a radial from a given center to the radius and an angle in degrees."""
x1, y1 = rpoint(x, y, r, ang)
result = plt.Line2D([x,x1], [y,y1], color='k', linestyle=style)
return result

def add_arc(x, y, r=1, ang1=0, ang2=0):
sr = r * 0.75
x1, y1 = rpoint(x, y, sr, ang2)
x2, y2 = rpoint(x, y, sr, ang2+15)
arc = Arc([x, y], sr*2, sr*2, angle=-100, theta1=ang2, theta2=ang1)
return arc

def add_arrow(x, y, r=1, ang1=0, ang2=0):
sr = r * 0.75
x1, y1 = rpoint(x, y, sr, ang2)
x2, y2 = rpoint(x, y, sr, ang2+10)
arrow = Arrow(x2, y2, x1-x2, y1-y2, color='k', linewidth=0.25)
return arrow

def add_lables(x, y, r, ang1, ang2, n):
x1, y1 = rpoint(x, y, r*1.21, ang1)
x2, y2 = rpoint(x, y, r*1.1, ang2)
text1 = plt.text(x1, y1, rf'$\theta_{n}$')
text2 = plt.text(x2, y2, rf'$\omega_{n}$')



Cell 4

fig, ax = plt.subplots()

centx, centy = 120, 120
item_count = 6
step = 360/item_count
offset = step/2
item_angs = [offset+step*n for n in range(item_count)]
#print(item_angs)
itemxys = [rpoint(centx, centy, radius, item_angs[n]) for n in range(item_count)]
items = [(*p, item_angs[n], n) for n,p in enumerate(itemxys)]
#print(items)

for x, y, ang, n in items:

for xy1, xy2 in itertools.combinations(itemxys, 2):
ax.add_artist(plt.Line2D([xy1[0], xy2[0]], [xy1[1], xy2[1]], color='lightgrey', linestyle=':'))

ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.plot()
plt.savefig('demo.svg')
plt.savefig('demo.png')
plt.savefig('demo.pdf')


Results in:

O.K I haven't varied the angles, the label offsets need more work, etc., but I think this is a good starting point. All of the information I used to get this far was either in the matplotlib manuals or examples.

The above code is available in a GitHub gist: https://gist.github.com/GadgetSteve/557b7c995a824af92f455f5f475948d5

• I am actually using jupyter notebook but i have no idea how draw such a diagram. Is there some sort of tutorial that explains how to draw such figures in matplotlib? Feb 29 '20 at 11:44
• @Miradius: I have added some example code and a link to a gist. Mar 1 '20 at 15:32
• Thx Steve! That looks really promising. I will try to workout the little details. Mar 2 '20 at 10:01