Ускорение точечных диаграмм matplotlib

Я пытаюсь создать интерактивную программу, которая в основном использует matplotlib для создания точечных диаграмм с большим количеством точек (10-100 тыс. или около того). Сейчас это работает, но изменения занимают слишком много времени. Небольшое количество очков — это нормально, но как только число увеличивается, все начинает быстро разочаровывать. Итак, я работаю над способами ускорения разброса, но мне не очень везет

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

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import time


X = np.random.randn(10000)  #x pos
Y = np.random.randn(10000)  #y pos
C = np.random.random(10000) #will be color
S = (1+np.random.randn(10000)**2)*3 #size

#build the colors from a color map
colors = mpl.cm.jet(C)
#there are easier ways to do static alpha, but this allows 
#per point alpha later on.
colors[:,3] = 0.1

fig, ax = plt.subplots()

fig.show()
background = fig.canvas.copy_from_bbox(ax.bbox)

#this makes the base collection
coll = ax.scatter(X,Y,facecolor=colors, s=S, edgecolor='None',marker='D')

fig.canvas.draw()

sTime = time.time()
for i in range(10):
    print i
    #don't change anything, but redraw the plot
    ax.cla()
    coll = ax.scatter(X,Y,facecolor=colors, s=S, edgecolor='None',marker='D')
    fig.canvas.draw()
print '%2.1f FPS'%( (time.time()-sTime)/10 )

Что дает быстрые 0,7 кадра в секунду

В качестве альтернативы я могу редактировать коллекцию, возвращаемую scatter. Для этого я могу изменить цвет и положение, но не знаю, как изменить размер каждой точки. Это, я думаю, выглядело бы примерно так

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import time


X = np.random.randn(10000)  #x pos
Y = np.random.randn(10000)  #y pos
C = np.random.random(10000) #will be color
S = (1+np.random.randn(10000)**2)*3 #size

#build the colors from a color map
colors = mpl.cm.jet(C)
#there are easier ways to do static alpha, but this allows 
#per point alpha later on.
colors[:,3] = 0.1

fig, ax = plt.subplots()

fig.show()
background = fig.canvas.copy_from_bbox(ax.bbox)

#this makes the base collection
coll = ax.scatter(X,Y,facecolor=colors, s=S, edgecolor='None', marker='D')

fig.canvas.draw()

sTime = time.time()
for i in range(10):
    print i
    #don't change anything, but redraw the plot
    coll.set_facecolors(colors)
    coll.set_offsets( np.array([X,Y]).T )
    #for starters lets not change anything!
    fig.canvas.restore_region(background)
    ax.draw_artist(coll)
    fig.canvas.blit(ax.bbox)
print '%2.1f FPS'%( (time.time()-sTime)/10 )

Это приводит к снижению скорости на 0,7 кадра в секунду. Я хотел попробовать использовать CircleCollection или RegularPolygonCollection, так как это позволило бы мне легко изменять размеры, и меня не волнует изменение маркера. Но я не могу заставить их рисовать, поэтому я понятия не имею, будут ли они быстрее. Итак, на данный момент я ищу идеи.


person george    schedule 12.08.2013    source источник
comment
Какую версию ты используешь?   -  person tacaswell    schedule 12.08.2013
comment
также см. github.com/matplotlib/matplotlib/pull/2156   -  person tacaswell    schedule 12.08.2013
comment
Python версии 2.7.3, matplotlib 1.2.0   -  person george    schedule 12.08.2013


Ответы (2)


Я проходил через это несколько раз, пытаясь ускорить точечные графики с большим количеством точек, по-разному пытаясь:

  • Различные типы маркеров
  • Ограничение цветов
  • Сокращение набора данных
  • Использование тепловой карты/сетки вместо точечной диаграммы

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

person John Lyon    schedule 12.08.2013
comment
Я действительно надеялся, что это не будет ответом, matplotlib чрезвычайно удобен. Есть ли шанс, что вы можете упомянуть некоторые из неподходящих замен matplotlib, которые вы пробовали, чтобы я не мог тратить время на то, чтобы узнать, что они не будут работать? Прямо сейчас первое место в моем списке вещей, которые стоит попробовать, это чако. - person george; 12.08.2013
comment
Я возился только с парой, но мы продолжали возвращаться к matplotlib, поскольку он наиболее удобен и хорошо поддерживается. Моим следующим портом захода будет rpy2, если мне нужно делать быстрые вещи, такие как ваш вопрос - R предназначен для больших данных, и можно предположить, что их графики довольно быстры: rpy.sourceforge.net/rpy2/doc-2.2/html/graphics.html - person John Lyon; 12.08.2013
comment
Я бы рекомендовал последние 2 варианта. Если вам просто нужна красивая визуальная презентация какого-то образца, нет смысла строить все это целиком. Диаграмма рассеяния подвыборки обычно должна быть в порядке. В качестве альтернативы вы можете собрать образец и отобразить какое-то крупнозернистое (а также, возможно, сглаженное, в зависимости от ваших потребностей) изображение, изменив цвет/интенсивность в соответствии со значением в каждом бине (или пикселе). Это позволяет вам сохранить matplotlib, не подвергая его слишком большой проблеме, с которой он может справиться. - person Cong Ma; 03.08.2015

Мы активно работаем над производительностью для больших диаграмм рассеяния matplotlib. Я призываю вас принять участие в обсуждении (http://matplotlib.1069221.n5.nabble.com/mpl-1-2-1-Speedup-code-by-removing-startswith-calls).-and-some-for-loops-td41767.html) и, что еще лучше, протестировать запрос на вытягивание, который был отправлен, чтобы сделать жизнь намного лучше для аналогичного случая (https://github.com/matplotlib/matplotlib/pull/2156).

ХТН

person pelson    schedule 15.08.2013