When I plot the following code with 3 subplots using matplotlib,
import numpy as np
import matplotlib.pyplot as plt
# ======================================
# Base ellipse parameters
# ======================================
a = 4 # semi-major axis
b = 1.2 # semi-minor axis
d = 0.65 # offset distance for parallel ellipse
# Generate parametric plot values
theta = np.linspace(0, 2 * np.pi, 400)
# Base ellipse (center at origin)
x = a * np.cos(theta)
y = b * np.sin(theta)
# ======================================
# 3. Confocal ellipses (same foci, derivatives)
# ======================================
# For base ellipse: c^2 = a^2 - b^2 (focus distance)
c = np.sqrt(a**2 - b**2)
# For confocal ellipse(smaller) : c stays constant, choose a2 < a
a_small = 4.2
b_small = np.sqrt(a_small**2 - c**2)
x_small_conf = a_small * np.cos(theta)
y_small_conf = b_small * np.sin(theta)
# For confocal ellipse(bigger) : c stays constant, choose new a2 > a
a_big = 4.6
b_big = np.sqrt(a_big**2 - c**2)
x_big_conf = a_big * np.cos(theta)
y_big_conf = b_big * np.sin(theta)
# ======================================
# Plotting
# ======================================
fig, axs = plt.subplots(1,3,figsize=(18, 7),constrained_layout=True) # plt.figure(figsize=(5.0, 7.0))
# c) Confocal ellipse
axs[2].plot(x, y, 'b', label='Base')
axs[2].plot(x_small_conf, y_small_conf, 'g--', label='Smaller Confocal')
axs[2].plot(x_big_conf, y_big_conf, 'r--', label='Bigger Confocal') # color='red', linestyle='--'
axs[2].set_title('Confocal Ellipses', pad=-15)
##-------------------------Ticks---------------------------------------------------------------------
xticks = np.arange(-a, a+1, a/2)
yticks = np.arange(-3*b, 3*b+1, b/2)
axs[2].set_xticks(xticks)
axs[2].set_yticks(yticks)
axs[2].minorticks_on()
#axs[2].grid(which='major', linestyle=':', linewidth='0.5', color='gray')
#axs[2].grid(which='minor', linestyle=':', linewidth='0.5', color='gray')
##-------------------------Grid arrows and labels---------------------------------------------------------------------
axs[2].set_xlabel("X", labelpad=15, loc='center')
axs[2].set_ylabel('Y', labelpad=14, rotation=0, va='center', ha='right')
axs[2].legend(loc='upper right', fontsize=8)
axs[2].axis('equal');
axs[2].grid(True)
axs[2].set_ylim(-8.0,8.0)
axs[2].set_aspect('equal', adjustable='box')
##------------------------- Focus and Center --------------------------------------------------------------------
c = np.sqrt(a**2 - b**2)
foci = [(-c, 0), (c, 0)]
axs[2].scatter(*zip(*foci), color='black', marker='o', s=25, label='Foci')
axs[2].plot(0, 0, 'o', color='black', markersize=8, label='Center')
#////////////////////////// Decorate properly ///////////////////////////////////////////////////////////////
axs[2].annotate('', xytext=(0.2, -0.08), textcoords='axes fraction',
xy=(1, -0.08), xycoords='axes fraction',
arrowprops=dict(arrowstyle='->', lw=1))
#////////////////////////////////////////////////////////////////////////////////////////////////////////////
#plt.tight_layout()
plt.show()
- embbed the label within xAxis & yAxis
- make the spline visible
- make extra tick-labels appear along y direction
- add a footer description of the figure
I'm lost with which API might be of use here! - any help I would appreciate!

