I have recently discovered matplotlib as a much better alternative to Matlab for plots. Unfortunately, my knowledge of python is close to zero.
Consider the following figure and the associated code.
import numpy as np
import scipy.io
from matplotlib import pyplot as plt
plt.figure(figsize=[3.3, 3.3])
plt.rcParams.update({'font.size': 8, 'text.usetex': True})
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], color='r')
plt.plot([1, 2, 3, 4], [2, 5, 10, 17], color='r')
plt.plot([1, 2, 3, 4], [11, 14, 19, 26], color='b')
plt.plot([1, 2, 3, 4], [12, 15, 20, 27], color='b')
plt.annotate('blue curves', xy=(1.5, 22.5), xytext=(1.5, 22.5), ha='center', va='center')
plt.annotate('', xy=(2, 15), xytext=(1.5, 22), arrowprops=dict(width=0.1, headwidth=2, headlength=2, color='grey'))
plt.annotate('red curves', xy=(2.5, 22.5), xytext=(2.5, 22.5), ha='center', va='center')
plt.annotate('', xy=(3, 10), xytext=(2.5, 22), arrowprops=dict(width=0.1, headwidth=2, headlength=2, color='grey'))
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('filename.pdf', format='pdf')
plt.show()
I'd like to add a small ellipse/circle to each arrow that encloses the curves. The ellipse/circle should have the same style of the arrow (i.e., color, thicknes, etc.). Is there an easy way to do this without modifying much the existing code?
I tried to get some inspiration from this example but it didn't work.
While you can call plot
and annotate
on your plt
-object, you will need to access the figure
and the axis
. A good explanation of the differences between plots, figures and axes is given here.
The code you will have to add (before plt.show()
):
from matplotlib.patches import Ellipse
fig = plt.gcf() # access the current figure
ax = plt.gca() # access the current axis
xmin, xmax = ax.get_xlim() # get the minimum and maximum extent of the x-axis
ymin, ymax = ax.get_ylim() # get the minimum and maximum extent of the y-axis
aspect_ratio = fig.get_figheight() / fig.get_figwidth() # get aspect ratio, we will use it to scale the width and height of the ellipse to appear as a circle
ax.add_patch(Ellipse(xy=(2, 15), width=(xmax-xmin)*aspect_ratio/5, height=(ymax-ymin)/5, color="grey", fill=False, lw=2))
ax.add_patch(Ellipse(xy=(3, 10), width=(xmax-xmin)*aspect_ratio/5, height=(ymax-ymin)/5, color="grey", fill=False, lw=2))