ここで(RAMに)問題があります:プロットしたいデータを保持できません。十分なHDスペースがあります。データセットの「シャドウイング」を回避する解決策はありますか?
具体的には、デジタル信号処理を扱い、高いサンプルレートを使用する必要があります。私のフレームワーク(GNU Radio)は、値を(過度のディスク領域の使用を避けるために)バイナリーに保存します。開梱します。その後、プロットする必要があります。プロットをズーム可能で、インタラクティブにする必要があります。そしてそれは問題です。
これに最適化の可能性、またはより大きなデータセットを処理できる別のソフトウェア/プログラミング言語(Rなど)がありますか?実際、プロットにはもっと多くのデータが必要です。しかし、他のソフトウェアの経験はありません。 GNUplotは失敗しますが、次のアプローチも同様です。 R(jet)がわかりません。
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import struct
"""
plots a cfile
cfile - IEEE single-precision (4-byte) floats, IQ pairs, binary
txt - index,in-phase,quadrature in plaintext
note: directly plotting with numpy results into shadowed functions
"""
# unpacking the cfile dataset
def unpack_set(input_filename, output_filename):
index = 0 # index of the samples
output_filename = open(output_filename, 'wb')
with open(input_filename, "rb") as f:
byte = f.read(4) # read 1. column of the vector
while byte != "":
# stored Bit Values
floati = struct.unpack('f', byte) # write value of 1. column to a variable
byte = f.read(4) # read 2. column of the vector
floatq = struct.unpack('f', byte) # write value of 2. column to a variable
byte = f.read(4) # next row of the vector and read 1. column
# delimeter format for matplotlib
lines = ["%d," % index, format(floati), ",", format(floatq), "\n"]
output_filename.writelines(lines)
index = index + 1
output_filename.close
return output_filename.name
# reformats output (precision configuration here)
def format(value):
return "%.8f" % value
# start
def main():
# specify path
unpacked_file = unpack_set("test01.cfile", "test01.txt")
# pass file reference to matplotlib
fname = str(unpacked_file)
plt.plotfile(fname, cols=(0,1)) # index vs. in-phase
# optional
# plt.axes([0, 0.5, 0, 100000]) # for 100k samples
plt.grid(True)
plt.title("Signal-Diagram")
plt.xlabel("Sample")
plt.ylabel("In-Phase")
plt.show();
if __== "__main__":
main()
Plt.swap_on_disk()のようなものがSSDにデータをキャッシュする可能性があります;)
したがって、データはそれほど大きくなく、プロットに問題があるという事実は、ツールの問題を示しています。 Matplotlib ....はそれほど良くありません。多くのオプションがあり、出力は問題ありませんが、メモリを大量に消費し、基本的にはデータが小さいと想定します。しかし、そこには他のオプションがあります。
例として、次を使用して20Mのデータポイントファイル「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 __== "__main__":
main()
これにより、サイズが最大229MBのファイルが生成されますが、それほど大きくありません。しかし、あなたはさらに大きなファイルに行きたいと表明したので、最終的にメモリの制限に達するでしょう。
最初に非対話型プロットに集中しましょう。最初に実現することは、各ポイントにグリフを含むベクトルプロットが災害になることです-20 Mポイントのそれぞれについて、ほとんどがとにかくオーバーラップし、小さな十字や円などをレンダリングしようとしています巨大なファイルを生成し、膨大な時間を費やして、災害になります。これは、デフォルトでmatplotlibを沈めているものだと思います。
Gnuplotはこれに対処するのに問題はありません:
gnuplot> set term png
gnuplot> set output 'foo.png'
gnuplot> plot 'bigdata.bin' binary format="%3float32" using 2:3 with dots
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 __== "__main__":
main()
ここで、インタラクティブにしたい場合は、プロットするデータをビン化し、その場でズームインする必要があります。 pythonこれを手伝うのに役立つツールはありません。
一方、plot-big-dataは非常に一般的なタスクであり、仕事に対応するツールがあります。 Paraview は私の個人的なお気に入りであり、 VisIt は別のお気に入りです。どちらも主に3Dデータ用ですが、特にParaviewも2Dを使用し、非常にインタラクティブです(さらに、Pythonスクリプトインターフェイス)もあります。唯一のトリックは、データを書き込むことですParaviewが簡単に読み取れるファイル形式。
ファイルの読み取りを確実に最適化できます。NumPyの生の速度を活用するために、NumPy配列に直接読み取ることができます。いくつかのオプションがあります。 RAMが問題である場合は、 memmap を使用できます。これにより、RAMの代わりにほとんどのファイルがディスクに保持されます。
_# Each data point is a sequence of three 32-bit floats:
data = np.memmap(filename, mode='r', dtype=[('index', 'float32'), ('floati','float32'), ('floatq', 'float32')])
_
RAMが問題にならない場合、配列全体をRAMで fromfile と指定できます。
_data = np.fromfile(filename, dtype=[('index', 'float32'), ('floati','float32'), ('floatq', 'float32')])
_
その後、Matplotlibの通常のplot(*data)
関数を使用して、別のソリューションで提案されている「ズームイン」メソッドを使用して、プロットを実行できます。
より最近のプロジェクトには、大きなデータセットの強力な可能性があります: Bokeh 、これは とまったく同じことを念頭に置いて作成されました 。
実際、プロットのスケールに関連するデータのみがディスプレイバックエンドに送信されます。このアプローチは、Matplotlibアプローチよりもはるかに高速です。
Ubuntuでの1000万点の散布図ベンチマークを使用したオープンソースのインタラクティブなプロットソフトウェアの調査
以下で説明されているユースケースに触発されました: https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier- r 次の非常に単純で素朴な1000万ポイントの直線データを使用して、いくつかの実装をベンチマークしました。
_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
_
基本的に、私はしたかった:
さらに楽しくするために、プログラムで1,000万ポイントを処理できるように、さらに大きい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')
_
これにより、_10m.csv
_のような直線と、グラフの中央上部に1つの外れ値を含む〜23GiBファイルが生成されます。
サブセクションで特に言及されていない限り、テストはUbuntu 18.10で、Intel Core i7-7820HQ CPU(4コア/ 8スレッド)、2x Samsung M471A2K43BB1-CRC RAM =(2x 16GiB)、NVIDIA Quadro M1200 4GB GDDR5 GPU。
結果の概要
これは、非常に具体的なテストユースケースと、レビューされたソフトウェアの多くを初めて使用するユーザーを考慮して、私が観察したものです。
1000万ポイントを処理しますか?
_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
_
多くの機能がありますか:
_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.
_
GUIは良い感じです(良いパフォーマンスを考慮していません):
_Vaex Yes, Jupyter widget
VisIt No
Paraview Very
Mayavi OK
gnuplot OK
matplotlib OK
Bokeh Very, Jupyter widget
_
Vaex 2.0.2
https://github.com/vaexio/vaex
インストールして、次のように動作するハローワールドを取得します。 Vaexでインタラクティブな2D散布図のズーム/ポイント選択を行う方法
最大10億ポイントでvaexをテストしましたが、うまくいきました。
これは「Python-scripted-first」であり、再現性に優れており、他のPythonものと簡単にインターフェイスできます。
Jupyterのセットアップにはいくつかの可動部分がありますが、virtualenvで実行すると、すごかったです。
JupyterでCSVを実行するには:
_import vaex
df = vaex.from_csv('10m.csv', names=['x', 'y', 'z'],)
df.plot_widget(df.x, df.y, backend='bqplot')
_
すぐに見ることができます:
これで、マウスでポイントをズーム、パン、選択できるようになり、更新が非常に高速になりました。ここでは、いくつかの個々のポイントを表示するためにズームインし、それらのいくつかを選択しました(画像上の薄い明るい長方形):
マウスで選択を行った後、これは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
_
1000万ポイントが問題なく機能したため、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')
_
生成するもの:
そして、ポイントを選択した後:
外れ値の完全なデータを取得します。
_ x y z
0 500000000 1500000000 -1
_
そのような個々のポイントをより見やすくする方法はありますか?質問: vaexインタラクティブJupyter bqplot plot_widgetのポイントスタイルを変更して、個々のポイントを大きく表示できるようにする方法
結果:動作します!!!!最初のロードには約10秒、マウスのズームと選択にはそれぞれ約3秒、最終的な選択の評価にも約10秒かかります。このような大規模なデータセットのすごいスピード。
これは、より興味深いデータセットとより多くの機能を備えた作成者によるデモです。 https://www.youtube.com/watch?v=2Tt0i823-ec&t=77
Ubuntu 19.04でテスト済み。
VisIt 2.13.3
ウェブサイト: https://wci.llnl.gov/simulation/computer-codes/visit
ライセンス:BSD
Lawrence Livermore National Laboratory 、これは National Nuclear Security Administration の研究所によって開発されたので、10mポイントはそれが機能するようになれば何の役にも立たないと想像できます。
インストール:Debianパッケージはありません。ウェブサイトからLinuxバイナリをダウンロードするだけです。インストールせずに実行します。参照: https://askubuntu.com/questions/966901/installing-visit
[〜#〜] vtk [〜#〜] に基づきます。これは、高性能グラフ作成ソフトウェアの多くが使用するバックエンドライブラリです。 Cで書かれた.
UIで3時間遊んだ後、私はそれを動作させ、次の場所で詳述されているようにユースケースを解決しました: https://stats.stackexchange.com/questions/376361/how-to-find-サンプルポイントが統計的に意味のある大きな外れ値r
この投稿のテストデータでは、次のようになります。
といくつかのピックでズーム:
ここにピックウィンドウがあります。
パフォーマンスに関しては、VisItは非常に優れていました。すべてのグラフィック操作は、ほんの少しの時間しかかからなかったか、すぐに行われ、より多くのデータを簡単に処理できると思います。私が待たなければならなかったとき、それは残っている仕事の割合で「処理」メッセージを表示し、GUIはフリーズしませんでした。
10mポイントがとてもうまくいったので、100mポイント(2.7G CSVファイル)も試しましたが、残念ながらクラッシュ/奇妙な状態になりました。4つのVisItスレッドがすべてを占有するので、htop
16GiB RAMであり、mallocの失敗が原因で死亡した可能性があります。
最初の開始は少し苦痛でした:
これらの問題の原因は次のとおりです。
また、LLNLインフラストラクチャの一部がそのレポにリークすることも気に入っています。たとえば、 docs/OfficeHours.txt およびそのディレクトリ内の他のファイルを参照してください! 「月曜日の朝の男」であるブラッド、ごめんなさい!ああ、留守番電話のパスワードは「Kill Ed」です。忘れないでください。
Paraview 5.4.1
ウェブサイト: https://www.paraview.org/
ライセンス:BSD
インストール:
_Sudo apt-get install paraview
_
Sandia National Laboratories によって開発されました。これは別のNNSAラボであるため、ここでもデータを簡単に処理できると期待しています。また、VTKベースでC++で記述されており、さらに有望でした。
しかし、私は失望しました:何らかの理由で、10mポイントでGUIが非常に遅くなり、応答しなくなりました。
よく宣伝された「私は今働いています。少し待ってください」という瞬間は問題ありませんが、GUIがフリーズしますか?受け入れられません。
htopは、Paraviewが4つのスレッドを使用していることを示しましたが、CPUとメモリのいずれも上限に達していませんでした。
GUIに関しては、Paraviewは非常に素晴らしく、モダンであり、VisItよりもst音がありません。ここでは、参照用にポイント数を減らしています。
ここに、手動でポイントを選択したスプレッドシートビューがあります。
別の欠点は、ParaviewがVisItと比較して機能が不足していると感じたことです。
マヤヴィ4.6.2
ウェブサイト: https://github.com/enthought/mayavi
開発者: Enthought
インストール:
_Sudo apt-get install libvtk6-dev
python3 -m pip install -u mayavi PyQt5
_
VTK Python one。
Mayaviは3Dに非常に焦点を当てているようで、その中で2Dプロットを行う方法を見つけることができなかったため、残念ながら私のユースケースでそれをカットしません。
ただし、パフォーマンスを確認するために、次の例を使用しました: https://docs.enthought.com/mayavi/mayavi/auto/example_scatter_plot.html 1000万ポイントで、遅れることなく正常に実行されます:
_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()
_
出力:
しかし、個々のポイントを表示するのに十分なズームインができませんでした。近くの3D平面が遠すぎました。たぶん方法がありますか?
Mayaviの素晴らしい点の1つは、開発者が多くの労力を費やして、Pythonスクリプト、Matplotlibやgnuplotによく似たスクリプトからGUIを起動およびセットアップできるようにすることです。これも可能であるようです。 Paraviewでは、しかしドキュメントは少なくともそれほど良くありません。
一般的に、VisIt/Paraviewのように機能が充実しているとは思えません。たとえば、GUIからCSVを直接読み込むことができませんでした: Mayavi GUIからCSVファイルを読み込む方法
Gnuplot 5.2.2
ウェブサイト: http://www.gnuplot.info/
gnuplotは手早く汚れる必要があるときに本当に便利で、常に最初に試すことです。
インストール:
_Sudo apt-get install gnuplot
_
非対話型の使用では、10mポイントを適切に処理できます。
_#!/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秒で終了しました:
しかし、私がとインタラクティブに行こうとすると
_#!/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
_
その後、最初のレンダリングとズームが遅く感じます。長方形の選択線さえ見えません!
また、私のユースケースでは、次のようにハイパーテキストラベルを使用する必要があることに注意してください。
_plot "10m.csv" using 1:2:3 with labels hypertext
_
ただし、非インタラクティブレンダリングを含むラベル機能にはパフォーマンスのバグがありました。しかし、私はそれを報告し、イーサンは一日でそれを解決しました: https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/qpL8aJIi9ZE
ただし、外れ値の選択には1つの合理的な回避策があると言わなければなりません。すべてのポイントに行IDのラベルを追加するだけです。近くに多くのポイントがある場合、ラベルを読み取ることができなくなります。しかし、あなたが気にする外れ値については、あなただけかもしれません!たとえば、元のデータに1つの外れ値を追加した場合:
_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分後)が、妥当な出力が生成されます。
そのため、何らかのデータフィルタリングを行うと、最終的にそこに到達します。
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秒かかりました...
それから、インタラクティブなものは最初のレンダリングとズームに長い時間がかかりました。使用できません:
このスクリーンショットでは、ズームが計算されるのを待っている間、すぐにズームして消えるはずのズーム選択が長時間画面に残っていることに注意してください!
インタラクティブバージョンが何らかの理由で機能するためには、plt.figure(figsize=(8, 8), dpi=128)
をコメントアウトする必要がありました。
_RuntimeError: In set_size: Could not set the fontsize
_
ボケ1.3.1
https://github.com/bokeh/bokeh
Ubuntu 19.04インストール:
_python3 -m pip install bokeh
_
次に、Jupyterを起動します。
_jupyter notebook
_
今、1mポイントをプロットすると、すべてが完璧に機能し、ズームやホバー情報など、インターフェースは素晴らしく高速です。
_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)
_
初期ビュー:
ズーム後:
窒息しても10mまで行けば、htop
は、クロムに8つのスレッドがあり、中断できないIO状態)ですべてのメモリを占有していることを示しています。
これは、ポイントの参照について尋ねます: 選択したボケデータポイントの参照方法
PyVizhttps://pyviz.org/
TODO評価。
Bokeh +データシェーダー+他のツールを統合します。
1Bデータポイントのデモビデオ: https://www.youtube.com/watch?v=k27MJJLJNT4 「PyViz:30行のPythonで10億のデータポイントを視覚化するためのダッシュボード」「Anaconda、Inc.」 2018年4月17日公開.
私は少し複雑なものを提案しますが、それはうまくいくはずです:さまざまな範囲のさまざまな解像度でグラフを構築します.
たとえば、Google Earthを考えてください。惑星全体をカバーするために最大レベルでズームを解除すると、解像度は最低になります。ズームすると、写真はより詳細なものに変わりますが、ズームしている領域のみです。
基本的にあなたのプロット(2D?3D?私は2Dだと仮定します)のために、低解像度で[0、n]範囲全体をカバーする1つの大きなグラフ、[0、n/2]と[n/2 + 1、n]は大きなものの2倍の解像度、[0、n/4] ... [3 * n/4 + 1、n]は2倍をカバーする4つの小さなグラフ上記2の解像度など。
私の説明が本当に明確かどうかわかりません。また、この種の多重解像度グラフが既存のプロットプログラムで処理されるかどうかもわかりません。
あなたのポイントの検索を高速化することで得られる勝利があるのだろうか? (私はしばらくの間、R *(r star)木に興味がありました。)
この場合、r *ツリーのようなものを使用するのがよいのではないかと思います。 (ズームアウトすると、ツリーの上位のノードには、より粗いズームアウトされたレンダリングに関する情報が含まれ、リーフに向かうノードには個々のサンプルが含まれます)
ツリー(または最終的に使用する構造)をメモリにメモリマップして、パフォーマンスを維持し、RAM使用率を低くします。(メモリ管理のタスクをカーネルにオフロードします)
それが理にかなっていることを願っています。遅いです!