Постройте градиентные стрелки над картой тепла с помощью PLT - PullRequest
0 голосов
/ 06 июля 2018

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

import matplotlib.pyplot as plt
import numpy as np
function_to_plot = lambda x, y: x + y ** 2
horizontal_min, horizontal_max, horizontal_stepsize = 0, 3, 0.3
vertical_min, vertical_max, vertical_stepsize = 0, 3, 0.6

xv, yv = np.meshgrid(np.arange(horizontal_min, horizontal_max, horizontal_stepsize), 
                     np.arange(vertical_min, vertical_max, vertical_stepsize))

result_matrix = function_to_plot(xv, yv)
xd, yd = np.gradient(result_matrix)

def func_to_vectorize(x, y, dx, dy, scaling=1):
    plt.arrow(x + horizontal_stepsize/2, y + vertical_stepsize/2, dx*scaling, dy*scaling, fc="k", ec="k", head_width=0.1, head_length=0.1)

vectorized_arrow_drawing = np.vectorize(func_to_vectorize)

plt.imshow(result_matrix, extent=[horizontal_min, horizontal_max, vertical_min, vertical_max])
vectorized_arrow_drawing(xv, yv, xd, yd, 1)
plt.colorbar()
plt.show()

Это результирующий сюжет:

Results

Я ожидал, что стрелки будут указывать на прямоугольники с наибольшим значением, но это не так. Чего мне не хватает?

1 Ответ

0 голосов
/ 06 июля 2018
  1. Похоже, что np.gradient() возвращает значения y перед значениями x
  2. Цвета также оказались неправильными, потому что значения y контекста графического изображения были перевернуты. Таким образом я использовал np.flip(result_matrix,0) во время построения
  3. Наконец, я заметил, что при построении стрелок имел место сбой, когда stepsize не делил регион равномерно, кроме того, сетка не была выровнена по центру прямоугольников. Я исправил оба этих кода в следующем коде:

enter image description here

Вот код, который я использовал для генерации графика:

import matplotlib.pyplot as plt
import numpy as np
import math
function_to_plot = lambda x, y: x**2 + y**2
horizontal_min, horizontal_max, horizontal_stepsize = -2, 3, 0.3
vertical_min, vertical_max, vertical_stepsize = -1, 4, 0.5

horizontal_dist = horizontal_max-horizontal_min
vertical_dist = vertical_max-vertical_min

horizontal_stepsize = horizontal_dist / float(math.ceil(horizontal_dist/float(horizontal_stepsize)))
vertical_stepsize = vertical_dist / float(math.ceil(vertical_dist/float(vertical_stepsize)))

xv, yv = np.meshgrid(np.arange(horizontal_min, horizontal_max, horizontal_stepsize),
                     np.arange(vertical_min, vertical_max, vertical_stepsize))
xv+=horizontal_stepsize/2.0
yv+=vertical_stepsize/2.0

result_matrix = function_to_plot(xv, yv)
yd, xd = np.gradient(result_matrix)

def func_to_vectorize(x, y, dx, dy, scaling=0.01):
    plt.arrow(x, y, dx*scaling, dy*scaling, fc="k", ec="k", head_width=0.06, head_length=0.1)

vectorized_arrow_drawing = np.vectorize(func_to_vectorize)

plt.imshow(np.flip(result_matrix,0), extent=[horizontal_min, horizontal_max, vertical_min, vertical_max])
vectorized_arrow_drawing(xv, yv, xd, yd, 0.1)
plt.colorbar()
plt.show()
...