Более быстрый способ обеспечить поворот к точкам рассеяния в matplotlib? - PullRequest
0 голосов
/ 22 февраля 2019

В настоящее время я использую следующее для построения набора повернутых линий (индикаторов геологического удара).Тем не менее, этот раздел кода занимает много времени, даже с небольшим количеством ударов (5000).Каждая точка имеет уникальное вращение.Есть ли способ дать matplotlib список с вращениями и выполнять построение быстрее, чем вращение по одному, как это?

sample=#3d-array of points(x,y,theta) where theta is an amount I want to rotate the points by.

    for i in range(len(sample.T)):
        t = matplotlib.markers.MarkerStyle(marker='|')
        t._transform = t.get_transform().rotate_deg(sample[2,i])
        plt.scatter(sample[0,i],sample[1,i],marker=t,s=50,c='0',linewidth=1)

1 Ответ

0 голосов
/ 22 февраля 2019

Здесь вы создаете 5000 отдельных точечных диаграмм.Это точно неэффективно.Вы можете использовать решение, которое я предложил в этом ответе , а именно, чтобы установить отдельные маркеры как пути к PathCollection.Это будет работать подобно разбросу, с дополнительным аргументом m для маркеров.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.markers as mmarkers

def mscatter(x,y,ax=None, m=None, **kw):
    import matplotlib.markers as mmarkers
    if not ax: ax=plt.gca()
    sc = ax.scatter(x,y,**kw)
    if (m is not None) and (len(m)==len(x)):
        paths = []
        for marker in m:
            if isinstance(marker, mmarkers.MarkerStyle):
                marker_obj = marker
            else:
                marker_obj = mmarkers.MarkerStyle(marker)
            path = marker_obj.get_path().transformed(
                        marker_obj.get_transform())
            paths.append(path)
        sc.set_paths(paths)
    return sc


np.random.seed(42)
data = np.random.rand(5000,3)
data[:,2] *= 360

markers = []
fig, ax = plt.subplots()
for i in range(len(data)):
    t = mmarkers.MarkerStyle(marker='|')
    t._transform = t.get_transform().rotate_deg(data[i,2])
    markers.append(t)
mscatter(data[:,0], data[:,1], m=markers, s=50, c='0', linewidth=1)

plt.show()

Если мы рассчитаем это время, мы обнаружим, что для создания графика с 5000 точками и 5000 различными значениями требуется ~ 250 мсуглы.В отличие от этого, решение цикла будет занимать более 12 секунд.

Пока что на общий вопрос о том, как вращать множество маркеров.Для особого случая здесь, кажется, вы хотите использовать простые линейные маркеры.Это легко сделать с помощью графика quiver.Затем можно отключить наконечники стрел, чтобы стрелки выглядели как линии.

fig, ax = plt.subplots()
ax.quiver(data[:,0], data[:,1], 1,1, angles=data[:,2]+90, scale=1/10, scale_units="dots",
          units="dots", color="k", pivot="mid",width=1, headwidth=1, headlength=0)

enter image description here

Результат почти такой же, сПреимущество этого графика составляет всего ~ 80 мс, что опять же в три раза быстрее, чем PathCollection.

...