Search code examples
pythonmatplotlibmachine-learninggraphleast-squares

Plot arrow on each point towards the line in graph


I am trying to plot arrows from each data point towards the line in the graph using matplotlib.

Graph

I want the arrow to represent the distance between each point and the line. How can I do this?

Here's my code:

import matplotlib.pyplot as plt
import numpy as np

# Create a straight line (45-degree angle)
x_line = np.linspace(0, 10, 100)
y_line = x_line

# Add some random points around the line
num_points = 20
x_points = np.linspace(2, 8, num_points)  # Adjust the range as needed
y_points = x_points + np.random.normal(0, 0.5, num_points)  # Add some randomness

# Plot the line
plt.plot(x_line, y_line, label='Line', color='blue')

# Plot the points
plt.scatter(x_points, y_points, label='Points', color='red')

# Set labels and title
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Scatter Plot Around a Line')

# Show legend
plt.legend()

# Display the plot
plt.show()

I tried doing this myself but failed: enter image description here

Code:

import matplotlib.pyplot as plt
import numpy as np

# Create a straight line (45-degree angle)
x_line = np.linspace(0, 10, 100)
y_line = x_line

# Add some random points around the line
num_points = 20
x_points = np.linspace(2, 8, num_points)  # Adjust the range as needed
y_points = x_points + np.random.normal(0, 0.5, num_points)  # Add some randomness

# Plot the line
plt.plot(x_line, y_line, label='Line', color='blue')

# Plot the points
plt.scatter(x_points, y_points, label='Points', color='red')

# Add arrows from each point to the line
for x, y in zip(x_points, y_points):
    plt.arrow(x, y, 0, y - x, color='black', linestyle='dashed', linewidth=0.5, head_width=0.2)

# Set labels and title
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Scatter Plot Around a Line')

# Show legend
plt.legend()

# Display the plot
plt.show()

As you can see the data points shifted and the arrows point outwards rather than inwards or towards the line.


Solution

  • You could edit this line so that it works in the reverse direction by replacing y - x with x - y:

    # Add arrows from each point to the line
    for x, y in zip(x_points, y_points):
        plt.arrow(x, y, 0, y- x, color='black', linestyle='dashed', linewidth=0.5, head_width=0.2)
    

    To:

    # Add arrows from each point to the line
    for x, y in zip(x_points, y_points):
        plt.arrow(x, y, 0, x - y, color='black', linestyle='dashed', linewidth=0.5, head_width=0.2)
    

    or you may use this code it might solve your issue.

    import matplotlib.pyplot as plt
    import numpy as np
    
    np.random.seed(42)
    
    # Create a straight line (45-degree angle)
    x_line = np.linspace(0, 10, 100)
    y_line = x_line
    
    # Add some random points around the line
    num_points = 20
    x_points = np.linspace(2, 8, num_points)  # Adjust the range as needed
    y_points = x_points + np.random.normal(0, 0.5, num_points)  # Add some randomness
    
    # Plot the line
    plt.plot(x_line, y_line, label='Line', color='blue')
    
    # Plot the points
    plt.scatter(x_points, y_points, label='Points', color='red')
    
    # Add outward arrows from each point away from the line
    for x, y in zip(x_points, y_points):
        plt.arrow(x, y, 0, x - y, color='black', linestyle='dashed', linewidth=0.5, head_width=0.2)
    
    # Set labels and title
    plt.xlabel('X-axis')
    plt.ylabel('Y-axis')
    plt.title('Scatter Plot Around a Line')
    
    # Show legend
    plt.legend()
    
    # Display the plot
    plt.show()