У меня есть проблема (с моей ОЗУ) здесь: она не может хранить данные, которые я хочу построить. У меня достаточно места для HD. Есть ли какое-либо решение, чтобы избежать "затенения" моего набора данных?
Конкретно я занимаюсь цифровой обработкой сигналов, и мне приходится использовать высокий уровень выборки. Моя инфраструктура (GNU Radio) сохраняет значения (во избежание использования большого количества дискового пространства) в двоичном формате. Я распакую его. Впоследствии мне нужно заговорить. Мне нужен сюжет, масштабируемый и интерактивный. И это проблема.
Есть ли какой-либо потенциал оптимизации для этого или другой язык программирования/программирования (например, R или около того), который может обрабатывать большие наборы данных? На самом деле я хочу получить гораздо больше данных на своих сюжетах. Но у меня нет опыта работы с другим программным обеспечением. GNUplot терпит неудачу, с аналогичным подходом к следующему. Я не знаю R (jet).
Ответ 1
Таким образом, ваши данные не такие большие, и тот факт, что у вас возникли проблемы с построением графика, указывает на проблемы с инструментами. Matplotlib.... не так уж хорошо. У этого есть много вариантов, и выход прекрасен, но это огромный всплеск памяти, и он принципиально предполагает, что ваши данные малы. Но есть и другие варианты.
Итак, в качестве примера я сгенерировал 20-мегабайтный файл данных "bigdata.bin", используя следующее:
#!/usr/bin/env python
import numpy
import scipy.io.numpyio
npts=20000000
filename='bigdata.bin'
def main():
data = (numpy.random.uniform(0,1,(npts,3))).astype(numpy.float32)
data[:,2] = 0.1*data[:,2]+numpy.exp(-((data[:,1]-0.5)**2.)/(0.25**2))
fd = open(filename,'wb')
scipy.io.numpyio.fwrite(fd,data.size,data)
fd.close()
if __name__ == "__main__":
main()
Это генерирует файл размером ~ 229 МБ, что не так уж и много; но вы выразили, что хотите перейти в более крупные файлы, чтобы в конечном итоге вы попали в пределы памяти.
Сначала сосредоточьтесь на неинтерактивных сюжетах. Первое, что нужно понять, - это то, что векторные графики с глифами в каждой точке будут катастрофой - для каждого из 20 М пунктов, большинство из которых будут пересекаться в любом случае, пытаясь сделать маленькие кресты или круги или что-то еще быть диастратом, генерировать огромные файлы и принимать тонны времени. Это, по-моему, то, что по умолчанию падает на matplotlib.
Gnuplot не имеет никакого отношения к этому:
gnuplot> set term png
gnuplot> set output 'foo.png'
gnuplot> plot 'bigdata.bin' binary format="%3float32" using 2:3 with dots
![gnuplot]()
И даже Matplotlib может вести себя с некоторой осторожностью (выбирая задний конец растра и используя пиксели для отметки точек):
#!/usr/bin/env python
import numpy
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
datatype=[('index',numpy.float32), ('floati',numpy.float32),
('floatq',numpy.float32)]
filename='bigdata.bin'
def main():
data = numpy.memmap(filename, datatype, 'r')
plt.plot(data['floati'],data['floatq'],'r,')
plt.grid(True)
plt.title("Signal-Diagram")
plt.xlabel("Sample")
plt.ylabel("In-Phase")
plt.savefig('foo2.png')
if __name__ == "__main__":
main()
![matplotlib]()
Теперь, если вы хотите использовать интерактивный интерфейс, вам нужно будет выровнять данные для построения и увеличить масштаб на лету. Я не знаю никаких инструментов python, которые помогут вам сделать это небрежно.
С другой стороны, plotting-big-data - довольно обычная задача, и есть инструменты, которые подходят для работы. Paraview - мой личный фаворит, а VisIt - еще один. Оба они в основном предназначены для трехмерных данных, но Paraview, в частности, делает и 2d, и является очень интерактивным (и даже имеет интерфейс сценариев Python). Единственный трюк - записать данные в формат файла, который может легко прочитать Paraview.
Ответ 4
Обзор программного обеспечения с открытым исходным кодом для интерактивного построения графиков с тестом рассеяния 10 миллионов точек на Ubuntu
Вдохновленный сценарием использования, описанным по адресу: https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier-r Я сравнил несколько реализаций со следующими очень простыми и наивными данными по прямой линии на 10 миллионов точек:
i=0;
while [ "$i" -lt 10000000 ]; do
echo "$i,$((2 * i)),$((4 * i))"; i=$((i + 1));
done > 10m.csv
Первые несколько строк 10m.csv
выглядят так:
0,0,0
1,2,4
2,4,8
3,6,12
4,8,16
В основном я хотел:
- сделать XY-диаграмму рассеяния многомерных данных, возможно, с Z в качестве цвета точки
- в интерактивном режиме выберите несколько интересных точек
- просмотрите все размеры выбранных точек, чтобы попытаться понять, почему они являются выбросами в разбросе XY
Чтобы получить дополнительное удовольствие, я также подготовил еще больший набор данных в 1 миллиард баллов на случай, если любая из программ сможет обработать 10 миллионов баллов! Файлы CSV становились немного шаткими, и я перешел на HDF5:
import h5py
import numpy
size = 1000000000
with h5py.File('1b.hdf5', 'w') as f:
x = numpy.arange(size + 1)
x[size] = size / 2
f.create_dataset('x', data=x, dtype='int64')
y = numpy.arange(size + 1) * 2
y[size] = 3 * size / 2
f.create_dataset('y', data=y, dtype='int64')
z = numpy.arange(size + 1) * 4
z[size] = -1
f.create_dataset('z', data=z, dtype='int64')
В результате получается файл размером ~ 23 ГБ, содержащий прямую линию, аналогичную 10m.csv
, и один выброс в центре вершины графика.
Тесты проводились в Ubuntu 18.10, если в подразделе не указано иное, в ноутбуке ThinkPad P51 с процессором Intel Core i7-7820HQ (4 ядра /8 потоков), 2x оперативной памятью Samsung M471A2K43BB1-CRC (2x 16 ГБ), NVIDIA Quadro M1200 4 ГБ GDDR5 GPU.
Сводка результатов
Это то, что я заметил, учитывая мой очень специфический вариант использования теста и то, что я впервые пользуюсь многими из рассмотренных программ:
Обрабатывает ли он 10 миллионов баллов:
Vaex Yes, tested up to 1 Billion!
VisIt Yes, but not 100m
Paraview Barely
Mayavi Yes
gnuplot Barely on non-interactive mode.
matplotlib No
Bokeh No, up to 1m
PyViz ?
seaborn ?
Много ли у него функций:
Vaex Yes.
VisIt Yes, 2D and 3D, focus on interactive.
Paraview Same as above, a bit less 2D features maybe.
Mayavi 3D only, good interactive and scripting support, but more limited features.
gnuplot Lots of features, but limited in interactive mode.
matplotlib Same as above.
Bokeh Yes, easy to script.
PyViz ?
seaborn ?
Чувствует ли себя графический интерфейс хорошо (не считая хорошей производительности):
Vaex Yes, Jupyter widget
VisIt No
Paraview Very
Mayavi OK
gnuplot OK
matplotlib OK
Bokeh Very, Jupyter widget
PyViz ?
seaborn ?
Vaex 2.0.2
https://github.com/vaexio/vaex
Установите и получите привет-мир, работающий, как показано на: Как сделать интерактивное масштабирование 2D точечного разброса/выбор точки в Vaex?
Я протестировал vaex с 1 миллиардом очков, и это сработало, это потрясающе!
Это "Python-scripted-first", который отлично подходит для воспроизводимости и позволяет мне легко взаимодействовать с другими вещами Python.
У установки Jupyter есть несколько движущихся частей, но как только я запустил его с virtualenv, это было удивительно.
Чтобы загрузить наш CSV, запустите в Jupyter:
import vaex
df = vaex.from_csv('10m.csv', names=['x', 'y', 'z'],)
df.plot_widget(df.x, df.y, backend='bqplot')
и мы сразу увидим:
![enter image description here]()
Теперь мы можем масштабировать, панорамировать и выбирать точки с помощью мыши, и обновления выполняются очень быстро, всего за 10 секунд. Здесь я увеличил масштаб, чтобы увидеть отдельные точки и выделил несколько из них (слабый светлый прямоangularьник на изображении):
![enter image description here]()
После того, как выбор сделан мышью, это имеет тот же эффект, что и метод df.select()
. Таким образом, мы можем извлечь выбранные точки, запустив в Jupyter:
df.to_pandas_df(selection=True)
который выводит данные в формате:
x y z index
0 4525460 9050920 18101840 4525460
1 4525461 9050922 18101844 4525461
2 4525462 9050924 18101848 4525462
3 4525463 9050926 18101852 4525463
4 4525464 9050928 18101856 4525464
5 4525465 9050930 18101860 4525465
6 4525466 9050932 18101864 4525466
Поскольку 10 миллионов баллов работали нормально, я решил попробовать 1B баллов!
import vaex
df = vaex.open('1b.hdf5')
df.plot_widget(df.x, df.y, backend='bqplot')
Чтобы наблюдать выброс, который был невидим на исходном графике, мы можем проследить Как изменить стиль точки в интерактивном vaex Jupyter bqplot plot_widget, чтобы сделать отдельные точки более крупными и видимыми? и использовать:
df.plot_widget(df.x, df.y, f='log', shape=128, backend='bqplot')
который производит:
![enter image description here]()
и после выбора точки:
![enter image description here]()
мы получаем полные данные выбросов:
x y z
0 500000000 1500000000 -1
Вот демонстрация создателей с более интересным набором данных и дополнительными функциями: https://www.youtube.com/watch?v=2Tt0i823-ec&t=770
Проверено в Ubuntu 19.04.
Визит 2.13.3
Веб-сайт: https://wci.llnl.gov/simulation/computer-codes/visit
Лицензия: BSD
Разработан Ливерморской национальной лабораторией им. Лоуренса, которая является лабораторией Национального управления по ядерной безопасности, поэтому вы можете себе представить, что 10 миллионов баллов для меня ничего не дадут, если я смогу заставить их работать.
Установка: нет пакета Debian, просто загрузите двоичные файлы Linux с веб-сайта. Работает без установки. Смотрите также: https://askubuntu.com/questions/966901/installing-visit
На основе VTK, которая является бэкэнд-библиотекой, которую используют многие графические программы с высокой производительностью. Написано на C.
После 3 часов игры с пользовательским интерфейсом, я все заработал, и он решил мой вариант использования, как описано на: https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier-r
Вот как это выглядит на тестовых данных этого поста:
![enter image description here]()
и увеличение с некоторыми выборами:
![enter image description here]()
и вот окно выбора:
![enter image description here]()
С точки зрения производительности VisIt был очень хорош: каждая графическая операция либо занимала небольшое количество времени, либо выполнялась незамедлительно, и я думаю, что она может легко обрабатывать гораздо больше данных. Когда мне пришлось ждать, оно показывает "обработку" сообщения с процентом оставшейся работы, и графический интерфейс не зависает.
Так как 10 миллионов точек работали очень хорошо, я также попробовал 100 миллионов точек (файл CSV 2,7 ГБ), но он, к сожалению, потерпел крах/перешел в странное состояние, я наблюдал это в htop
, поскольку 4 потока VisIt занимали всю мою 16 ГБ ОЗУ и скорее всего, умер из-за сбоя malloc.
Начальное начало было немного болезненным:
- многие из дефолтов чувствуют себя ужасно, если вы не инженер по атомной бомбе? Например.:
- размер точки по умолчанию 1px (запутывается от пыли на моем мониторе)
- масштаб осей от 0,0 до 1,0: Как отобразить фактические значения числа осей в программе построения графиков Визит вместо дробей от 0,0 до 1,0?
- многооконные настройки, неприятные множественные всплывающие окна при выборе точек данных
- показывает ваше имя пользователя и график (удалите с помощью "Controls"> "Аннотация"> "Информация о пользователе")
- автоматическое позиционирование по умолчанию плохое: легенда конфликтует с осями, не может найти автоматизацию заголовка, поэтому пришлось добавить метку и переместить все вручную
- функций просто много, поэтому сложно найти то, что вы хотите
- Руководство было очень полезным,
, но это мамонт в 386 страницах, зловеще датированный "Октябрь 2005 г., версия 1.5". Интересно, использовали ли они это для разработки Trinity!, и это красивый Сфинкс HTML, созданный сразу после того, как я первоначально ответил на этот вопрос
- нет пакета Ubuntu. Но встроенные двоичные файлы просто работали.
Я связываю эти проблемы с:
- он существует уже очень давно и использует некоторые устаревшие идеи графического интерфейса
- Вы не можете просто щелкнуть по элементам графика, чтобы изменить их (например, оси, заголовок и т.д.), и есть много функций, поэтому найти тот, который вы ищете, довольно сложно,
Мне также нравится, как немного инфраструктуры LLNL просачивается в это репо. Смотрите, например, docs/OfficeHours.txt и другие файлы в этом каталоге! Я извиняюсь за Брэда, который является "парнем в понедельник утром"! Да, и пароль для автоответчика - "Убить Эда", не забывайте об этом.
Paraview 5.4.1
Веб-сайт: https://www.paraview.org/
Лицензия: BSD
Установка:
sudo apt-get install paraview
Разработано Sandia National Laboratories, которая является еще одной лабораторией NNSA, поэтому мы снова ожидаем, что она легко обработает данные. Также VTK основан и написан на C++, что было еще более перспективным.
Однако я был разочарован: по каким-то причинам, 10 миллионов очков сделали GUI очень медленным и не отвечающим.
Я в порядке с контролируемым хорошо разрекламированным моментом "Я работаю сейчас, подожди немного", но GUI зависает, пока это происходит? Недопустимо.
htop показал, что Paraview использует 4 потока, но ни процессор, ни память не были загружены.
С точки зрения графического интерфейса, Paraview очень красивый и современный, намного лучше, чем VisIt, когда он не заикается. Вот это для подсчета очков:
![enter image description here]()
и вот электронная таблица с ручным выбором точек:
![enter image description here]()
Другим недостатком является то, что Paraview чувствовал недостаток функций по сравнению с VisIt, например:
Mayavi 4.6.2
Веб-сайт: https://github.com/enthought/mayavi
Разработано: Enthought
Установка:
sudo apt-get install libvtk6-dev
python3 -m pip install -u mayavi PyQt5
VTK Python один.
Mayavi, кажется, очень сосредоточен на 3D, я не мог найти, как сделать 2D-графики в нем, поэтому он, к сожалению, не подходит для моего случая использования.
Однако, просто для проверки производительности, я адаптировал пример из: https://docs.enthought.com/mayavi/mayavi/auto/example_scatter_plot.html для 10 миллионов баллов, и он отлично работает, не отставая:
import numpy as np
from tvtk.api import tvtk
from mayavi.scripts import mayavi2
n = 10000000
pd = tvtk.PolyData()
pd.points = np.linspace((1,1,1),(n,n,n),n)
pd.verts = np.arange(n).reshape((-1, 1))
pd.point_data.scalars = np.arange(n)
@mayavi2.standalone
def main():
from mayavi.sources.vtk_data_source import VTKDataSource
from mayavi.modules.outline import Outline
from mayavi.modules.surface import Surface
mayavi.new_scene()
d = VTKDataSource()
d.data = pd
mayavi.add_source(d)
mayavi.add_module(Outline())
s = Surface()
mayavi.add_module(s)
s.actor.property.trait_set(representation='p', point_size=1)
main()
Выход:
![enter image description here]()
Однако я не смог увеличить масштаб достаточно, чтобы увидеть отдельные точки, ближняя трехмерная плоскость была слишком далеко. Может быть, есть способ?
В Mayavi есть одна замечательная вещь: разработчики приложили немало усилий, чтобы вы могли красиво запускать и настраивать GUI из скрипта Python, очень похоже на Matplotlib и gnuplot. Кажется, что это также возможно в Paraview, но документы не так хороши, по крайней мере.
Как правило, он не так удобен, как VisIt/Paraview. Например, я не могу напрямую загрузить CSV из графического интерфейса: Как загрузить файл CSV из графического интерфейса Mayavi?
Gnuplot 5.2.2
Веб-сайт: http://www.gnuplot.info/
gnuplot очень удобен, когда мне нужно идти быстро и грязно, и это всегда первое, что я пробую.
Установка:
sudo apt-get install gnuplot
Для неинтерактивного использования он может достаточно хорошо обрабатывать 10 миллионов баллов:
#!/usr/bin/env gnuplot
set terminal png size 1024,1024
set output "gnuplot.png"
set key off
set datafile separator ","
plot "10m1.csv" using 1:2:3:3 with labels point
который закончился через 7 секунд:
![enter image description here]()
Но если я попытаюсь пообщаться с
#!/usr/bin/env gnuplot
set terminal wxt size 1024,1024
set key off
set datafile separator ","
plot "10m.csv" using 1:2:3 palette
и:
gnuplot -persist main.gnuplot
тогда начальный рендер и масштабирование кажутся слишком вялыми. Я даже не вижу линию выделения прямоangularьника!
Также обратите внимание, что для моего случая использования мне нужно было использовать гипертекстовые метки, как в:
plot "10m.csv" using 1:2:3 with labels hypertext
но была ошибка производительности с функцией надписей, в том числе для неинтерактивного рендеринга. Но я сообщил об этом, и Итан решил это за один день: https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/qpL8aJIi9ZE
Однако я должен сказать, что есть один разумный обходной путь для выбора выбросов: просто добавьте метки с идентификатором строки ко всем точкам! Если поблизости будет много точек, вы не сможете прочитать ярлыки. Но для выбросов, которые вас волнуют, вы просто можете! Например, если я добавлю одно отклонение к нашим исходным данным:
cp 10m.csv 10m1.csv
printf '2500000,10000000,40000000\n' >> 10m1.csv
и измените команду plot на:
#!/usr/bin/env gnuplot
set terminal png size 1024,1024
set output "gnuplot.png"
set key off
set datafile separator ","
plot "10.csv" using 1:2:3:3 palette with labels
Это значительно замедлило построение графика (через 40 минут после исправления, упомянутого выше), но дает приемлемый результат:
![enter image description here]()
так что с некоторой фильтрацией данных, мы бы в конечном итоге добрались.
Matplotlib 1.5.1, numpy 1.11.1, Python 3.6.7
Веб-сайт: https://matplotlib.org/
Matplotlib - это то, что я обычно пробую, когда мой скрипт gnuplot начинает становиться слишком безумным.
numpy.loadtxt
один занял около 10 секунд, поэтому я знал, что это не будет хорошо:
#!/usr/bin/env python3
import numpy
import matplotlib.pyplot as plt
x, y, z = numpy.loadtxt('10m.csv', delimiter=',', unpack=True)
plt.figure(figsize=(8, 8), dpi=128)
plt.scatter(x, y, c=z)
# Non-interactive.
#plt.savefig('matplotlib.png')
# Interactive.
plt.show()
Сначала неинтерактивная попытка дала хороший результат, но заняла 3 минуты 55 секунд...
Затем интерактивное заняло много времени при первоначальном рендеринге и увеличении. Не используется:
![enter image description here]()
Обратите внимание, что на этом скриншоте выделение масштабирования, которое должно немедленно увеличиваться и исчезать, оставалось на экране в течение длительного времени, пока оно ожидало вычисления масштаба!
Мне пришлось закомментировать plt.figure(figsize=(8, 8), dpi=128)
, чтобы интерактивная версия работала по какой-то причине, иначе она взорвалась:
RuntimeError: In set_size: Could not set the fontsize
Bokeh 1.3.1
https://github.com/bokeh/bokeh
Установка Ubuntu 19.04:
python3 -m pip install bokeh
Затем запустите Jupyter:
jupyter notebook
Теперь, если я наберу 1 миллион точек, все работает отлично, интерфейс потрясающий и быстрый, включая увеличение и информацию при наведении курсора:
from bokeh.io import output_notebook, show
from bokeh.models import HoverTool
from bokeh.transform import linear_cmap
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
import numpy as np
N = 1000000
source = ColumnDataSource(data=dict(
x=np.random.random(size=N) * N,
y=np.random.random(size=N) * N,
z=np.random.random(size=N)
))
hover = HoverTool(tooltips=[("z", "@z")])
p = figure()
p.add_tools(hover)
p.circle(
'x',
'y',
source=source,
color=linear_cmap('z', 'Viridis256', 0, 1.0),
size=5
)
show(p)
Исходный вид:
![enter image description here]()
После увеличения:
![enter image description here]()
Если я поднимусь до 10 м, хотя он и задохнется, htop
покажет, что хром имеет 8 потоков, занимающих всю мою память в состоянии бесперебойного ввода-вывода.
Это запрашивает ссылку на точки: Как ссылаться на выбранные точки данных боке
PyViz
https://pyviz.org/
TODO оценить.
Интегрирует Bokeh + datashader + другие инструменты.
Видео демонстрирует точки данных 1B: https://www.youtube.com/watch?v=k27MJJLJNT4 "PyViz: информационные панели для визуализации 1 миллиарда точек данных в 30 строках Python" от Anaconda, Inc. опубликовано 2018-04-17.
Сиборн
https://seaborn.pydata.org/
TODO оценить.
На уже есть QA, как использовать seaborn для визуализации не менее 50 миллионов строк.