Как ускорить рисование графиков в Matplotlib?

Я играю со случайным блужданием, у меня два очка. Первый идет хаотично, второй пытается выбраться из своей области, которая задается формулой e^(-t), где t — расстояние между двумя точками. На мой взгляд, это не сложная программа, но ее запуск с сотней точек для расчета занимает около минуты, поэтому я прошу вас помочь мне найти способ ускорить ее и объяснить мне.

import numpy as np
import matplotlib.pyplot as plt


def f(x, y, zx, zy):
    return np.exp(-np.sqrt((x-zx)**2+(y-zy)**2))


x = y = np.linspace(-100, 100, 1000)
X, Y = np.meshgrid(x, y)

fig, ax = plt.subplots(1, 1, figsize=(12, 6))
#random picking first location for two points
loksx = [np.random.randn(), ]
loksy = [np.random.randn(), ]
lokzx = [np.random.randn(), ]
lokzy = [np.random.randn(), ]
for i in range(100):
    lokzx.append(np.random.randn()+lokzx[-1])
    lokzy.append(np.random.randn()+lokzy[-1])
    nsx = np.random.randn()
    nsy = np.random.randn()
    #checking if the next step has smaller value than the last one 
    if f(loksx[-1]+nsx, loksy[-1]+nsy, lokzx[-1], lokzy[-1]) < f(loksx[-1], loksy[-1], lokzx[-1], lokzy[-1]):
        loksx.append(nsx+loksx[-1])
        loksy.append(nsy+loksy[-1])
Z = []
for i in range(len(lokzx)):
    Z.append(f(X, Y, lokzx[i], lokzy[i]))
ax.plot(lokzx[0], lokzy[0], 'y,',markersize=1)
ax.plot(loksx[0], loksy[0], 'w,', markersize=1)
ax.plot(lokzx[1:-1], lokzy[1:-1], 'g,',markersize=1)
ax.plot(loksx[1:-1], loksy[1:-1], 'b,', markersize=1)

ax.plot(loksx[-1], loksy[-1], 'k,', markersize=1)
ax.plot(lokzx[-1], lokzy[-1], 'r,',markersize=1)
for i in range(len(Z)):
    ax.contourf(X, Y, Z[i], 20, cmap='RdGy', alpha=0.01)
ax.plot()
ax.set_aspect('equal')
plt.show()

@редактировать Теперь вместо списков я использую nparrays:

import numpy as np
import matplotlib.pyplot as plt


def f(x, y, zx, zy):
    return np.exp(-np.sqrt((x-zx)**2+(y-zy)**2))


x = y = np.linspace(-100, 100, 1000)
X, Y = np.meshgrid(x, y)

fig, ax = plt.subplots(1, 1, figsize=(12, 6))
lokzx = np.random.randn(100)
lokzy = np.random.randn(100)
loksx = np.zeros(100)
loksy = np.zeros(100)
for i in range(1,100):
    nsx = np.random.randn()
    nsy = np.random.randn()
    if f(loksx[i-1]+nsx, loksy[i-1]+nsy, lokzx[i-1], lokzy[i-1]) < f(loksx[i-1], loksy[i-1], lokzx[i-1], lokzy[i-1]):
        loksx[i] = loksx[i-1]+nsx
        loksy[i] = loksy[i-1]+nsy
    else:
        loksx[i] = loksx[i-1]
        loksy[i] = loksy[i-1]
Z = np.zeros((100,1000,1000))
for i in range(len(lokzx)):
    Z[i] = f(X, Y, lokzx[i], lokzy[i])

ax.plot(lokzx[0], lokzy[0], 'y,',markersize=1)
ax.plot(loksx[0], loksy[0], 'w,', markersize=1)
ax.plot(lokzx[1:-1], lokzy[1:-1], 'g,',markersize=1)
ax.plot(loksx[1:-1], loksy[1:-1], 'b,', markersize=1)

ax.plot(loksx[-1], loksy[-1], 'k,', markersize=1)
ax.plot(lokzx[-1], lokzy[-1], 'r,',markersize=1)
for i in range(len(Z)):
    ax.contourf(X, Y, Z[i], 20, cmap='RdGy', alpha=0.01)
ax.plot()
ax.set_aspect('equal')
plt.show()

Но все же требуется время, чтобы запустить это. Единственная оставшаяся проблема - это две строки кода:

for i in range(len(Z)):
    ax.contourf(X, Y, Z[i], 20, cmap='RdGy', alpha=0.01)

Но я не знаю, как переписать это без использования цикла.

Это, вероятно, не заговор, который является медленным. Скорее всего это петли.

iamchoosinganame 29.05.2019 23:03

здесь есть хорошая документация: bastibe.de/2013-05-30-speeding-up-matplotlib.html

Masoud 29.05.2019 23:06

Хорошо, вы звоните контуру 1000 раз. Это точно будет медленно. Непонятно, почему вы 1000 раз звоните в контур.

Jody Klymak 30.05.2019 16:05

@JodyKlymak, потому что я хочу увидеть, какая площадь была в каждой точке

padar 30.05.2019 16:09

Можете ли вы связать изображение с тем, что вы пытаетесь сделать?

Jody Klymak 30.05.2019 16:10

@JodyKlymak вот что я пытаюсь сделать: imgur.com/a/JXdnZB8

padar 30.05.2019 16:39

Изображение на Imagur просто бордового цвета по осям...

Jody Klymak 30.05.2019 17:22

@JodyKlymak здесь у вас более увеличенная версия: imgur.com/a/YTmj7vL

padar 30.05.2019 17:28

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

Jody Klymak 30.05.2019 17:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
9
309
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны попытаться избежать циклов, научившись использовать соответствующие функции numpy. то есть что-то вроде ниже будет намного быстрее:

dx = np.random.randn(100)
dy = np.random.randn(100)
x = np.cumsum(dx)
y = np.cumsum(dy)

Если вам В самом деле нужен цикл for, предварительно выделите свой массив; не продолжайте добавлять:

x = np.zeros(100)
y = np.zeros(100)
for i in range(1, 100):
    x[i] = x[i-1] + np.random.randn()
    y[i] = y[i-1] + np.random.randn()

Несмотря на изменения, ему все еще нужно время, чтобы нарисовать его. Я думаю, что основная проблема заключается в этом цикле: python for i in range(len(Z)): ax.contourf(X, Y, Z[i], 20, cmap='RdGy', alpha=0.01) но я не знаю, как я могу написать это по-другому.

padar 29.05.2019 23:43

Другие вопросы по теме