Reputation: 1165
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
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
.
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)
Upvotes: 3
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()
Upvotes: 2