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.
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."""
rang = np.deg2rad(deg)
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):
""" Draw the arrow radius."""
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):
""" Draw the arrow head."""
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):
""" Add the lables."""
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}$')
def add_item(ax, x, y, rad, n, ang1, ang2, theta_ang):
""" Add a single item."""
ax.add_patch(get_circle(x, y, rad))
ax.add_artist(radial(x, y, rad, ang1))
ax.add_artist(radial(x, y, rad, ang2, '--'))
ax.add_patch(add_arc(x, y, rad, ang1, ang2))
ax.add_patch(add_arrow(x, y, rad, ang1, ang2))
add_lables(x, y, rad, (ang1+ang2)/2, theta_ang, n)
Cell 4
fig, ax = plt.subplots()
centx, centy = 120, 120
radius = 30
item_rad = 9
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:
add_item(ax, x, y, item_rad, n, 145, 45, ang-offset)
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.set_aspect('equal', adjustable='datalim')
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')
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