<p><strong>在Ubuntu上使用1000万点散点图基准的开源交互式绘图软件综述</p>
<p>受<a href="https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier-r">https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier-r</a>中描述的用例的启发,我使用以下非常简单和天真的1000万点直线数据对一些实现进行了基准测试:</p>
<pre><code>i=0;
while [ "$i" -lt 10000000 ]; do
echo "$i,$((2 * i)),$((4 * i))"; i=$((i + 1));
done > 10m.csv
</code></pre>
<p><code>10m.csv</code>的前几行如下:</p>
<pre><code>0,0,0
1,2,4
2,4,8
3,6,12
4,8,16
</code></pre>
<p>基本上,我想:</p>
<ul>
<li>做多维数据的XY散点图,希望用Z作为点颜色</li>
<li>交互选择一些有趣的观察点</li>
<li>查看所选点的所有维度,以尝试理解它们为何在XY散点图中是异常值</li>
</ul>
<p>为了获得更多乐趣,我还准备了一个更大的10亿点数据集,以防任何程序可以处理1000万点!CSV文件有点不稳定,我转到HDF5:</p>
<pre><code>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')
</code></pre>
<p>这将生成一个~23GiB文件,其中包含:</p>
<ul>
<li>10亿个点在一条直线上,很像<code>10m.csv</code></li>
<li>图中央顶部的一个异常点</li>
</ul>
<p>这些测试是在Ubuntu18.10中进行的,除非a小节中另有说明,在一台ThinkPad P51笔记本电脑上,配备Intel Core i7-7820HQ CPU(4核/8线程)、2x Samsung M471A2K43BB1-CRC RAM(2x 16GiB)、NVIDIA Quadro M1200 4GB GDDR5 GPU。</p>
<p><strong>结果摘要</strong></p>
<p>这就是我观察到的,考虑到我非常具体的测试用例,并且我是许多被审查的软件的第一次用户:</p>
<p>它能处理1000万点吗:</p>
<pre><code>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 ?
</code></pre>
<p>它有很多特点吗:</p>
<pre><code>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 ?
</code></pre>
<p>图形用户界面是否感觉良好(不考虑良好的性能):</p>
<pre><code>Vaex Yes, Jupyter widget
VisIt No
Paraview Very
Mayavi OK
gnuplot OK
matplotlib OK
Bokeh Very, Jupyter widget
PyViz ?
seaborn ?
</code></pre>
<p><strong>Vaex 2.0.2</strong></p>
<p><a href="https://github.com/vaexio/vaex" rel="nofollow noreferrer">https://github.com/vaexio/vaex</a></p>
<p>安装并获得一个hello world,如下所示:<a href="https://stackoverflow.com/questions/57323126/how-to-do-interactive-2d-scatter-plot-zoom-point-selection-in-vaex/57408827#57408827">How to do interactive 2D scatter plot zoom / point selection in Vaex?</a></p>
<p>我用高达10亿分测试了vaex,它成功了,太棒了!</p>
<p>它是“先编写Python脚本”的,这对于可重复性非常好,并且允许我轻松地与其他Python事物进行交互。</p>
<p>Jupyter的设置有几个移动部分,但是一旦我用virtualenv运行了它,它就非常棒了。</p>
<p>要在Jupyter中加载CSV运行:</p>
<pre><code>import vaex
df = vaex.from_csv('10m.csv', names=['x', 'y', 'z'],)
df.plot_widget(df.x, df.y, backend='bqplot')
</code></pre>
<p>我们可以立即看到:</p>
<p><a href="https://i.stack.imgur.com/Isxim.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Isxim.png" alt="enter image description here"/></a></p>
<p>现在,我们可以用鼠标缩放、平移和选择点,更新速度非常快,都在10秒内完成。在这里,我放大看到了一些单独的点,并选择了其中的一些点(图像上较浅的矩形):</p>
<p><a href="https://i.stack.imgur.com/PbY4C.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/PbY4C.png" alt="enter image description here"/></a></p>
<p>使用鼠标进行选择后,这与使用<code>df.select()</code>方法的效果完全相同。所以我们可以通过运行Jupyter来提取所选的点:</p>
<pre><code>df.to_pandas_df(selection=True)
</code></pre>
<p>输出数据格式:</p>
<pre><code> 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
</code></pre>
<p>既然10米的成绩不错,我决定试试1米的成绩!</p>
<pre><code>import vaex
df = vaex.open('1b.hdf5')
df.plot_widget(df.x, df.y, backend='bqplot')
</code></pre>
<p>要观察原始图上看不到的异常值,我们可以遵循<a href="https://stackoverflow.com/questions/57445642/how-change-the-point-style-in-a-vaex-interactive-jupyter-bqplot-plot-widget-to-m/57586292#57586292">How change the point style in a vaex interactive Jupyter bqplot plot_widget to make individual points larger and visible?</a>并使用:</p>
<pre><code>df.plot_widget(df.x, df.y, f='log', shape=128, backend='bqplot')
</code></pre>
<p>产生:</p>
<p><a href="https://i.stack.imgur.com/t5c29.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/t5c29.png" alt="enter image description here"/></a></p>
<p>选择点后:</p>
<p><a href="https://i.stack.imgur.com/Kzduh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Kzduh.png" alt="enter image description here"/></a></p>
<p>我们得到离群值的完整数据:</p>
<pre><code> x y z
0 500000000 1500000000 -1
</code></pre>
<p>下面是创建者的演示,其中包含更有趣的数据集和更多功能:<a href="https://www.youtube.com/watch?v=2Tt0i823-ec&t=770" rel="nofollow noreferrer">https://www.youtube.com/watch?v=2Tt0i823-ec&t=770</a></p>
<p>在Ubuntu19.04中测试。</p>
<p><strong>访问2.13.3</strong></p>
<p>网址:<a href="https://wci.llnl.gov/simulation/computer-codes/visit" rel="nofollow noreferrer">https://wci.llnl.gov/simulation/computer-codes/visit</a></p>
<p>许可证:BSD</p>
<p>由<a href="https://en.wikipedia.org/wiki/Lawrence_Livermore_National_Laboratory" rel="nofollow noreferrer">Lawrence Livermore National Laboratory</a>开发的,这是一个<a href="https://en.wikipedia.org/wiki/National_Nuclear_Security_Administration" rel="nofollow noreferrer">National Nuclear Security Administration</a>实验室,所以你可以想象,如果我能让它工作的话,10米的积分对它来说是没有意义的。</p>
<p>安装:没有Debian包,只需从网站下载Linux二进制文件。运行而不安装。另请参见:<a href="https://askubuntu.com/questions/966901/installing-visit">https://askubuntu.com/questions/966901/installing-visit</a></p>
<p>基于<a href="https://en.wikipedia.org/wiki/VTK" rel="nofollow noreferrer">VTK</a>这是许多高性能绘图软件使用的后端库。用C</p>
<p>在玩了3个小时的UI之后,我确实让它工作了,并且它确实解决了我的用例,详细内容如下:<a href="https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier-r">https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier-r</a></p>
<p>以下是这篇文章的测试数据:</p>
<p><a href="https://i.stack.imgur.com/gK11w.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gK11w.png" alt="enter image description here"/></a></p>
<p>放大一些照片ks公司:</p>
<p><a href="https://i.stack.imgur.com/zXqHw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zXqHw.png" alt="enter image description here"/></a></p>
<p>这里是picks窗口:</p>
<p><a href="https://i.stack.imgur.com/GCRXd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GCRXd.png" alt="enter image description here"/></a></p>
<p>从性能上看,访问非常好:每一个图形操作要么只花了很少的时间,要么是立即的,我认为它可以轻松地处理更多的数据。当我不得不等待时,它会显示一条“正在处理”消息,显示剩余工作的百分比,并且GUI不会冻结。</p>
<p>由于10m点工作得很好,我也尝试了100m点(一个2.7G CSV文件),但它崩溃了/进入了一个奇怪的状态不幸的是,我在<code>htop</code>中看到它,因为4个访问线程占用了我所有的16GiB内存,很可能是由于malloc失败而死亡。</p>
<p>最初的开始有点痛苦:</p>
<ul>
<li>如果你不是核弹工程师,很多违约行为都会让你觉得很糟糕?例如。:
<ul>
<li>默认点大小1px(与显示器上的灰尘混淆)</li>
<li>轴比例从0.0到1.0:<a href="https://stackoverflow.com/questions/56965558/how-to-show-the-actual-axes-number-values-on-the-visit-plotting-program-instead">How to show the actual axes number values on the Visit plotting program instead of fractions from 0.0 to 1.0?</a></li>
<li>多窗口设置,当您选择数据点时,会出现令人讨厌的多弹出窗口</li>
<li>显示用户名和打印日期(用“控件”>;“注释”>;“用户信息”删除)</li>
<li>自动定位默认值不好:图例与轴冲突,找不到标题自动,因此必须添加标签并手动重新定位所有内容</li>
</ul></li>
<li>有很多功能,所以很难找到你想要的</li>
<li>该手册非常有用,<s>但它是一个386页的PDF猛犸象不祥的日期“2005年10月版本1.5”。我想知道他们是不是用这个来开发<a href="https://en.wikipedia.org/wiki/Trinity_(nuclear_test)" rel="nofollow noreferrer">Trinity</a>!</s>它是在我最初回答这个问题之后创建的<a href="https://visit-sphinx-github-user-manual.readthedocs.io/en/develop/index.html" rel="nofollow noreferrer">nice Sphinx HTML</a></li>
<li>没有Ubuntu包。但预先构建的二进制文件确实起了作用。</li>
</ul>
<p>我把这些问题归咎于:</p>
<ul>
<li>它已经存在了这么长时间,并且使用了一些过时的GUI思想</li>
<li>你不能只点击绘图元素来改变它们(例如轴、标题等),而且有很多功能,所以很难找到你想要的</li>
</ul>
<p>我也喜欢一点LLNL基础设施如何泄漏到repo中。请参阅该目录中的示例<a href="https://github.com/visit-dav/visit/blob/60cff675d5e0f3f2180866efcb7db3a21850dc41/docs/OfficeHours.txt" rel="nofollow noreferrer">docs/OfficeHours.txt</a>和其他文件!我很抱歉布拉德是“星期一早上的家伙”!哦,答录机的密码是“Kill Ed”,别忘了。</p>
<p><strong>全景5.4.1</strong></p>
<p>网址:<a href="https://www.paraview.org/" rel="nofollow noreferrer">https://www.paraview.org/</a></p>
<p>许可证:BSD</p>
<p>安装:</p>
<pre><code>sudo apt-get install paraview
</code></pre>
<p>由<a href="https://en.wikipedia.org/wiki/Sandia_National_Laboratories" rel="nofollow noreferrer">Sandia National Laboratories</a>开发,这是另一个NNSA实验室,所以我们再次期待它能轻松处理数据。另外,VTK的基础上,用C++编写,这是进一步的承诺。</p>
<p>但是我很失望:由于某些原因,1000万点让GUI非常慢,而且没有反应。</p>
<p>我很好的控制广告“我现在工作,等一下”的时刻,但图形用户界面冻结而发生的事情?不可接受。</p>
<p>htop显示Paraview使用了4个线程,但是CPU和内存都没有耗尽。</p>
<p>从图形用户界面上看,Paraview非常漂亮和现代,在不结巴的情况下比访问要好得多。这里有一个较低的点数供参考:</p>
<p><a href="https://i.stack.imgur.com/FsEYA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FsEYA.png" alt="enter image description here"/></a></p>
<p>下面是电子表格视图,其中包含手动选择点:</p>
<p><a href="https://i.stack.imgur.com/bInJM.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bInJM.png" alt="enter image description here"/></a></p>
<p>另一个缺点是,与访问相比,Paraview感觉缺少功能,例如:</p>
<ul>
<li>我找不到如何根据第三列设置散布的颜色:<a href="https://stackoverflow.com/questions/55933181/how-to-color-scatter-plot-points-by-the-value-of-a-third-column-in-paraview-like">How to color scatter plot points by the value of a third column in Paraview like gnuplot palette?</a></li>
<li>无法调整标记大小!!!<a href="https://gitlab.kitware.com/paraview/paraview/issues/14169" rel="nofollow noreferrer">https://gitlab.kitware.com/paraview/paraview/issues/14169</a></li>
</ul>
<p><strong>梅亚维4.6.2</strong></p>
<p>网址:<a href="https://github.com/enthought/mayavi" rel="nofollow noreferrer">https://github.com/enthought/mayavi</a></p>
<p>开发人:<a href="https://en.wikipedia.org/wiki/Enthought" rel="nofollow noreferrer">Enthought</a></p>
<p>安装:</p>
<pre><code>sudo apt-get install libvtk6-dev
python3 -m pip install -u mayavi PyQt5
</code></pre>
<p>VTKPython一号。</p>
<p>Mayavi似乎非常专注于3D,我找不到如何在其中进行2D绘图,所以很不幸,它没有为我的用例裁剪它。</p>
<p>不过,为了检查性能,我将来自:<a href="https://docs.enthought.com/mayavi/mayavi/auto/example_scatter_plot.html" rel="nofollow noreferrer">https://docs.enthought.com/mayavi/mayavi/auto/example_scatter_plot.html</a>的示例修改了1000万个点,它运行得很好,没有滞后:</p>
<pre><code>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()
</code></pre>
<p>输出:</p>
<p><a href="https://i.stack.imgur.com/B3xm0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/B3xm0.png" alt="enter image description here"/></a></p>
<p>但是我不能放大到足以看到个人所有的点,近三维平面太远了。也许有办法?</p>
<p>Mayavi的一个很酷的地方是,开发人员花了很多精力让您能够很好地从Python脚本启动和设置GUI,就像Matplotlib和gnuplot一样。在Paraview中,这似乎也是可能的,但文档至少没有那么好。</p>
<p>一般来说,它不像VisIt/Paraview那样具有特色。例如,我无法直接从GUI加载CSV:<a href="https://stackoverflow.com/questions/55949572/how-to-load-a-csv-file-from-the-mayavi-gui">How to load a CSV file from the Mayavi GUI?</a></p>
<p><strong>Gnuplot 5.2.2</strong></p>
<p>网址:<a href="http://www.gnuplot.info/" rel="nofollow noreferrer">http://www.gnuplot.info/</a></p>
<p>gnuplot在我需要快速和脏兮兮的时候非常方便,而且它总是我尝试的第一件事。</p>
<p>安装:</p>
<pre><code>sudo apt-get install gnuplot
</code></pre>
<p>对于非交互使用,它可以很好地处理10米点:</p>
<pre><code>#!/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
</code></pre>
<p>在7秒内完成:</p>
<p><a href="https://i.stack.imgur.com/FsEYA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FsEYA.png" alt="enter image description here"/></a></p>
<p>但如果我想和</p>
<pre><code>#!/usr/bin/env gnuplot
set terminal wxt size 1024,1024
set key off
set datafile separator ","
plot "10m.csv" using 1:2:3 palette
</code></pre>
<p>以及:</p>
<pre><code>gnuplot -persist main.gnuplot
</code></pre>
<p>然后,初始渲染和缩放感觉太慢。我甚至看不到矩形选择线!</p>
<p>还要注意,对于我的用例,我需要使用超文本标签,如下所示:</p>
<pre><code>plot "10m.csv" using 1:2:3 with labels hypertext
</code></pre>
<p>但是标签功能有一个性能缺陷,包括非交互式渲染。但我报告了,伊桑一天就解决了:<a href="https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/qpL8aJIi9ZE" rel="nofollow noreferrer">https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/qpL8aJIi9ZE</a></p>
<p>不过,我必须说,对于异常值选择有一个合理的解决方法:只需向所有点添加具有行ID的标签!如果附近有很多点,你将无法阅读标签。但是对于那些你关心的异类,你可能会!例如,如果在原始数据中添加一个异常值:</p>
<pre><code>cp 10m.csv 10m1.csv
printf '2500000,10000000,40000000\n' >> 10m1.csv
</code></pre>
<p>并将plot命令修改为:</p>
<pre><code>#!/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
</code></pre>
<p>这显著减慢了绘图速度(在上述修复后40分钟),但产生了合理的输出:</p>
<p><a href="https://i.stack.imgur.com/hha1B.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/hha1B.png" alt="enter image description here"/></a></p>
<p>所以通过一些数据过滤,我们最终会达到目的。</p>
<p><strong>Matplotlib 1.5.1、numpy 1.11.1、Python 3.6.7</p>
<p>网址:<a href="https://matplotlib.org/" rel="nofollow noreferrer">https://matplotlib.org/</a></p>
<p>当我的gnuplot脚本开始变得太疯狂时,Matplotlib是我通常尝试的。</p>
<p><code>numpy.loadtxt</code>一个人花了大约10秒,所以我知道这不会顺利:</p>
<pre><code>#!/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()
</code></pre>
<p>首先,非交互式的尝试给出了很好的输出,但花了3分55秒。。。</p>
<p>然后交互式的在初始渲染和缩放上花费了很长时间。不可用:</p>
<p><a href="https://i.stack.imgur.com/fCjvz.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fCjvz.png" alt="enter image description here"/></a></p>
<p>请注意这个屏幕截图上的缩放选择,它应该立即缩放并消失在屏幕上停留很长一段时间,同时等待缩放计算!</p>
<p>我不得不注释掉<code>plt.figure(figsize=(8, 8), dpi=128)</code>以便交互式版本出于某种原因工作,否则它会爆炸:</p>
<pre><code>RuntimeError: In set_size: Could not set the fontsize
</code></pre>
<p><strong>第1.3.1节</strong></p>
<p><a href="https://github.com/bokeh/bokeh" rel="nofollow noreferrer">https://github.com/bokeh/bokeh</a></p>
<p>Ubuntu 19.04安装:</p>
<pre><code>python3 -m pip install bokeh
</code></pre>
<p>然后启动Jupyter:</p>
<pre><code>jupyter notebook
</code></pre>
<p>现在如果我画出1米的点,一切都很好,界面很棒,速度也很快,包括缩放和悬停信息:</p>
<pre><code>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)
</code></pre>
<p>初始视图:</p>
<p><a href="https://i.stack.imgur.com/ZDpCD.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ZDpCD.png" alt="enter image description here"/></a></p>
<p>缩放后:</p>
<p><a href="https://i.stack.imgur.com/bkmUW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bkmUW.png" alt="enter image description here"/></a></p>
<p>如果我到了10m,尽管它阻塞了,<code>htop</code>显示chromium有8个线程在不间断IO状态下占用了我的所有内存。</p>
<p>这询问关于引用点:<a href="https://stackoverflow.com/questions/32909068/how-to-reference-selected-bokeh-data-points">How to reference selected bokeh data points</a></p>
<p><strong>PyViz</strong></p>
<p><a href="https://pyviz.org/" rel="nofollow noreferrer">https://pyviz.org/</a></p>
<p>待办事项评估。</p>
<p>集成Bokeh+datashader+其他工具。</p>
<p>视频演示1B数据点:<a href="https://www.youtube.com/watch?v=k27MJJLJNT4" rel="nofollow noreferrer">https://www.youtube.com/watch?v=k27MJJLJNT4</a>“PyViz:30行Python中的10亿数据点可视化仪表板”,由“Anaconda,Inc.”发布于2018-04-17。</p>
<p><strong>西伯恩</strong></p>
<p><a href="https://seaborn.pydata.org/" rel="nofollow noreferrer">https://seaborn.pydata.org/</a></p>
<p>待办事项评估。</p>
<p>在<a href="https://stackoverflow.com/a/51027895/5675325">how to use seaborn to visualize at least 50 million rows</a>上已经有一个QA。</p>