0

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()

3rd subplot needs improvement I was not able to :

  1. embbed the label within xAxis & yAxis
  2. make the spline visible
  3. make extra tick-labels appear along y direction
  4. add a footer description of the figure

I'm lost with which API might be of use here! - any help I would appreciate!

1 Answer 1

0

For question 1, you can draw two line segments — one with an arrow and one without — and place two line segments exactly on both sides of the label.

axs[2].annotate('',  xytext=(0.2, -0.08), xy=(0.45, -0.08),
                      xycoords='axes fraction',
                      arrowprops=dict(arrowstyle='-', lw=1))
axs[2].annotate('',  xytext=(0.55, -0.08), xy=(1, -0.08),
                      xycoords='axes fraction',
                      arrowprops=dict(arrowstyle='->', lw=1))

For Q2, I'm not sure which plaform you used to draw the picture, but in jupyter, the right spine is visible.

For Q3, you can plt.MaxNLocator to increase the tick-labels.

axs[2].yaxis.set_major_locator(plt.MaxNLocator(15))

For Q4, you can use Axes.text.

axs[2].text(0, -10, "Confocal Ellipses", ha='center',color='red')

The final figure: enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.