Elena Greg
Elena Greg

Reputation: 1165

How to plot normal vectors in each point of the curve with a given length?

How to plot normal vectors in each point of the curve with a given length?

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
plt.rcParams["figure.figsize"] = [8, 8]

x = np.linspace(-1, 1, 100)
y = x**2
ax.set_ylim(-0.3, 1.06)
ax.plot(x, y)

plt.show()

Upvotes: 2

Views: 4528

Answers (2)

Reblochon Masque
Reblochon Masque

Reputation: 36662

To plot the normals, you need to calculate the slope at each point; from there, you get the tangent vector that you can rotate by pi/2.

enter image description here

here is one approach using python i/o np, which makes it probably easier to understand at first.

Changing the length will adjust the size of the normals to properly scale with your plot.

import matplotlib.pyplot as plt
import numpy as np
import math

def get_normals(length=.1):
    
    for idx in range(len(x)-1):
        x0, y0, xa, ya = x[idx], y[idx], x[idx+1], y[idx+1]
        dx, dy = xa-x0, ya-y0
        norm = math.hypot(dx, dy) * 1/length
        dx /= norm
        dy /= norm
        
        ax.plot((x0, x0-dy), (y0, y0+dx))    # plot the normals


fig, ax = plt.subplots()
plt.rcParams["figure.figsize"] = [8, 8]

x = np.linspace(-1, 1, 100)
y = x**2
ax.set_ylim(-0.3, 1.06)
ax.plot(x, y)
get_normals()


plt.show()

or longer normals, directed downwards: get_normals(length=-.3) (use ax.set_aspect('equal') to maintain angles)

enter image description here

Upvotes: 3

Lior Cohen
Lior Cohen

Reputation: 5735

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
plt.rcParams["figure.figsize"] = [8, 8]

x = np.linspace(-1, 1, 100)
y = x**2

# Calculating the gradient
L=.1 # gradient length
grad = np.ones(shape = (2, x.shape[0]))
grad[0, :] = -2*x
grad /= np.linalg.norm(grad, axis=0)  # normalizing to unit vector

nx = np.vstack((x - L/2 * grad[0], x + L/2 * grad[0]))
ny = np.vstack((y - L/2 * grad[1], y + L/2 * grad[1]))

# ax.set_ylim(-0.3, 1.06)
ax.plot(x, y)
ax.plot(nx, ny, 'r')
ax.axis('equal')

plt.show()

enter image description here

Upvotes: 2

Related Questions