0

I can't get my head around recreating the attached image. I looked into fancy arrows and so on but I can't create the blue and red arrow.

This is what I have so far:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
from scipy.stats import norm

# Generate random data from a continuous distribution (e.g., normal distribution)
data = np.random.normal(0, 1, 100)  # Mean = 0, Standard Deviation = 1

# Calculate the CDF
sorted_data = np.sort(data)
cdf = np.arange(1, len(sorted_data) + 1) / len(sorted_data)

plt.figure(figsize=(8, 6))
plt.plot(sorted_data, cdf, label='Empirical CDF')

# Generate random points on the x and y axes
random_x = np.random.choice(sorted_data, 1)[0]
random_y = np.random.uniform(0, 1, 1)[0]

# Plot arrows
arrow1 = FancyArrowPatch((random_x, 0), (random_x, random_y), color='red', arrowstyle='-|>', mutation_scale=15)
arrow2 = FancyArrowPatch((0, random_y), (random_x, random_y), color='blue', arrowstyle='-|>', mutation_scale=15)
plt.gca().add_patch(arrow1)
plt.gca().add_patch(arrow2)

plt.annotate(f'({random_x:.2f}, {random_y:.2f})', (random_x + 0.1, random_y + 0.02), color='black')

plt.title('Cumulative Distribution Function (CDF) with Arrows')
plt.xlabel('X-axis')
plt.ylabel('Cumulative Probability')
plt.legend()
plt.grid(True)
plt.show()

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
bunus19
  • 55
  • 5

1 Answers1

-1

From the image it seems like the random values for x and y do not correspond to each other but should be used separately for the different colored arrows. And for each color, the arrow is turning towards one axis, as soon as it hits the curve. Therefore I splitted each arrow into 2 parts, one pointing towards the curve (arrowi1) and one point away from the curve (arrowi2). Also you will need plt.xlim() in order to reach the leftmost part of the plot.

# generate random index in order to access x/y corresponding to the curve
idx_x = np.random.choice(range(len(sorted_data)), 1)[0]
random_x = sorted_data[idx_x]

idx_y = np.random.choice(range(len(sorted_data)), 1)[0]
random_y = cdf[idx_y]

# Plot arrows
arrow11 = FancyArrowPatch((random_x, 0), (random_x, cdf[idx_x]), color='red', arrowstyle='-', mutation_scale=15)
arrow12 = FancyArrowPatch((random_x, cdf[idx_x]), (plt.xlim()[0], cdf[idx_x]), color='red', arrowstyle='-|>', mutation_scale=15)

arrow21 = FancyArrowPatch((plt.xlim()[0], random_y), (sorted_data[idx_y], random_y), color='blue', arrowstyle='-', mutation_scale=15)
arrow22 = FancyArrowPatch((sorted_data[idx_y], random_y), (sorted_data[idx_y], 0), color='blue', arrowstyle='-|>', mutation_scale=15)

plt.gca().add_patch(arrow11)
plt.gca().add_patch(arrow12)
plt.gca().add_patch(arrow21)
plt.gca().add_patch(arrow22)


Flow
  • 551
  • 1
  • 3
  • 9