2015-07-17 3 views
5

Я хотел бы нарисовать стрелку, указывающую градиент функции в точке, указав в направлении касание к функции. Я хотел бы, чтобы длина длины этой стрелки была пропорциональна размеру оси, чтобы она была видна при любом уровне масштабирования.Направление стрелки, заданное данными, но длина, установленная размером фигуры

Скажем, мы хотим нарисовать производную от x^2 по номеру x=1 (производная составляет 2). Вот две вещи, которые я пробовал:

import matplotlib.pyplot as plt 
import numpy as np 

fig = plt.figure() 
ax = fig.add_subplot(111) 

x = np.linspace(0, 2, 1000) 
y = x**2 
ax.plot(x, y) 

x, y = (1.0, 1.0) 
grad = 2.0 

# Fixed size, wrong direction 
len_pts = 40 
end_xy = (len_pts, len_pts*grad) 

ax.annotate("", xy=(x, y), xycoords='data', 
     xytext=end_xy, textcoords='offset points', 
     arrowprops=dict(arrowstyle='<-', connectionstyle="arc3")) 

# Fixed direction, wrong size 
len_units = 0.2 
end_xy = (x+len_units, y+len_units*grad) 

ax.annotate("", xy=(x, y), xycoords='data', 
     xytext=end_xy, textcoords='data', 
     arrowprops=dict(arrowstyle='<-', connectionstyle="arc3")) 

ax.axis((0,2,0,2)) 
plt.show() 

Вот как они выглядят на двух уровнях масштабирования. Чтобы было ясно, Я хочу длину красной линии в направлении и черной линии в:

enter image description hereenter image description here

ответ

4

В вашем случае, это звучит, как вы хотите quiver. Параметры масштабирования сначала немного запутывают, а поведение по умолчанию отличается от того, что вы хотите. Тем не менее, вся точка колчана - дать вам контроль над тем, как размер, угол и масштабирование взаимодействуют при изменении размера сюжета.

Например:

import matplotlib.pyplot as plt 
import numpy as np 

fig, ax = plt.subplots() 

x = np.linspace(0, 2, 1000) 
y = x**2 
ax.plot(x, y) 

x0, y0 = 1.0, 1.0 
dx, dy = 1, 2 

length = 1.25 # in inches 
dx, dy = length * np.array([dx, dy])/np.hypot(dx, dy) 

ax.quiver(x0, y0, dx, dy, units='inches', angles='xy', scale=1, 
      scale_units='inches', color='red') 

ax.axis((0, 2, 0, 2)) 
plt.show() 

enter image description here

Ключевую роль здесь

units='inches', angles='xy', scale=1 

angles='xy' указывает, что мы хотим, чтобы вращение/угол стрелки, чтобы быть в блоков данных (т. е. соответствовать градиенту графической кривой, в данном случае).

scale=1 говорит, что не автомасштабировать длину стрелки, а вместо этого нарисуйте размер, который мы даем ему, с указанными нами единицами.

units='inches' сообщает quiver для интерпретации нашего dx, dy как находящегося в дюймах.

Я не уверен, что в этом случае действительно нужен scale_units (по умолчанию он должен быть равен units), но он позволяет стрелке иметь разную длину, чем единица ширины.

И как изменить размер участка, угол остается в блоках данных, но длина остается в дюймах (т.е. постоянной длины на экране):

enter image description here

+0

отлично работает. – supergra

Смежные вопросы