web-dev-qa-db-fra.com

Grand graphique interactif avec environ 20 millions de points d'échantillonnage et gigaoctets de données

J'ai un problème (avec ma RAM) ici: il ne peut pas contenir les données que je veux tracer. J'ai suffisamment d'espace HD. Existe-t-il une solution pour éviter cette "observation" de mon ensemble de données?

Concrètement, je m'occupe du traitement numérique du signal et je dois utiliser un taux d'échantillonnage élevé. Mon framework (GNU Radio) enregistre les valeurs (pour éviter d'utiliser trop d'espace disque) en binaire. Je le déballe. Ensuite, j'ai besoin de comploter. J'ai besoin de l'intrigue zoomable et interactive. Et c'est un problème.

Y a-t-il un potentiel d'optimisation à cela, ou un autre langage de programmation/logiciel (comme R ou plus) qui peut gérer de plus grands ensembles de données? En fait, je veux beaucoup plus de données dans mes parcelles. Mais je n'ai aucune expérience avec d'autres logiciels. GNUplot échoue, avec une approche similaire à la suivante. Je ne connais pas 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()

Quelque chose comme plt.swap_on_disk () pourrait mettre en cache les trucs sur mon SSD;)

61
wishi

Vos données ne sont donc pas si grandes, et le fait que vous ayez du mal à les tracer indique des problèmes avec les outils. Matplotlib .... n'est pas si bon. Il a beaucoup d'options et la sortie est bonne, mais c'est un énorme porc de mémoire et il suppose fondamentalement que vos données sont petites. Mais il existe d'autres options.

Ainsi, à titre d'exemple, j'ai généré un fichier de points de données de 20 millions de données 'bigdata.bin' en utilisant ce qui suit:

#!/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()

Cela génère un fichier de taille ~ 229 Mo, ce qui n'est pas si gros; mais vous avez dit que vous aimeriez aller dans des fichiers encore plus gros, donc vous atteindrez éventuellement les limites de mémoire.

Concentrons-nous d'abord sur les tracés non interactifs. La première chose à réaliser est que les tracés vectoriels avec des glyphes à chaque point vont être un désastre - pour chacun des 20 M points, dont la plupart vont se chevaucher de toute façon, essayant de rendre de petites croix ou cercles ou quelque chose va être un diaster, générer des fichiers énormes et prendre des tonnes de temps. C'est, je pense, ce qui coule par défaut matplotlib.

Gnuplot n'a aucun mal à gérer cela:

gnuplot> set term png
gnuplot> set output 'foo.png'
gnuplot> plot 'bigdata.bin' binary format="%3float32" using 2:3 with dots

gnuplot

Et même Matplotlib peut être amené à se comporter avec une certaine prudence (en choisissant un back-end raster et en utilisant des pixels pour marquer des points):

#!/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()  

matplotlib

Maintenant, si vous voulez interactif, vous allez devoir regrouper les données à tracer et zoomer à la volée. Je ne connais pas d'outils python qui vous aideront à faire cela à la légère.

D'un autre côté, le traçage des données volumineuses est une tâche assez courante, et il existe des outils prêts à l'emploi. Paraview est mon préféré, et VisIt en est un autre. Ils sont tous deux principalement destinés aux données 3D, mais Paraview en particulier fait également 2d, et est très interactif (et a même une interface de script Python). La seule astuce sera d'écrire les données dans un format de fichier que Paraview peut facilement lire.

68
Jonathan Dursi

Vous pouvez certainement optimiser la lecture de votre fichier: vous pouvez le lire directement dans un tableau NumPy, afin de tirer parti de la vitesse brute de NumPy. Vous avez quelques options. Si RAM est un problème, vous pouvez utiliser memmap , qui conserve la plupart du fichier sur le disque (au lieu de la 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')])

Si RAM n'est pas un problème, vous pouvez mettre tout le tableau dans RAM avec fromfile :

data = np.fromfile(filename, dtype=[('index', 'float32'), ('floati','float32'), ('floatq', 'float32')])

Le traçage peut alors être effectué avec la fonction habituelle plot(*data) de Matplotlib, éventuellement par la méthode de "zoom avant" proposée dans une autre solution.

12
Eric O Lebigot

Un projet plus récent a un fort potentiel pour les grands ensembles de données: Bokeh , qui a été créé avec exactement cela à l'esprit .

En fait, seules les données pertinentes à l'échelle du tracé sont envoyées au backend d'affichage. Cette approche est beaucoup plus rapide que l'approche Matplotlib.

11
Eric O Lebigot

Une enquête sur un logiciel de traçage interactif open source avec un benchmark de 10 millions de points de dispersion sur Ubuntu

Inspiré du cas d'utilisation décrit à: https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier- r J'ai comparé quelques implémentations avec les données linéaires de 10 millions de points très simples et naïves suivantes:

i=0;
while [ "$i" -lt 10000000 ]; do
  echo "$i,$((2 * i)),$((4 * i))"; i=$((i + 1));
done > 10m.csv

Les premières lignes de 10m.csv Ressemblent à ceci:

0,0,0
1,2,4
2,4,8
3,6,12
4,8,16

Fondamentalement, je voulais:

  • faire un diagramme de dispersion XY de données multidimensionnelles, avec, espérons-le, Z comme couleur de point
  • sélectionner de manière interactive des points de vue intéressants
  • afficher toutes les dimensions des points sélectionnés pour essayer de comprendre pourquoi ils sont aberrants dans le nuage XY

Pour m'amuser encore plus, j'ai également préparé un ensemble de données d'un milliard de points encore plus grand au cas où l'un des programmes pourrait gérer les 10 millions de points! Les fichiers CSV devenaient un peu chancelants, je suis passé à 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')

Cela produit un fichier ~ 23GiB contenant une ligne droite comme 10m.csv Et une valeur aberrante en haut au centre du graphique.

Les tests ont été effectués dans Ubuntu 18.10 sauf indication contraire dans la sous-section, dans un ordinateur portable ThinkPad P51 avec processeur Intel Core i7-7820HQ (4 cœurs/8 threads), 2x Samsung M471A2K43BB1-CRC RAM = (2 x 16 Go), GPU NVIDIA Quadro M1200 4 Go GDDR5.

Résumé des résultats

C'est ce que j'ai observé, compte tenu de mon cas d'utilisation de test très spécifique et du fait que je suis un premier utilisateur de nombreux logiciels examinés:

Gère-t-il 10 millions de points:

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

At-il beaucoup de fonctionnalités:

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.

L'interface graphique se sent-elle bien (sans considérer de bonnes performances):

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

Installez et faites fonctionner un monde bonjour comme indiqué dans: Comment faire une sélection interactive de zoom/point de nuage de points en Vaex?

J'ai testé le vaex avec jusqu'à 1 milliard de points et ça a marché, c'est génial!

C'est "Python-scripted-first" qui est excellent pour la reproductibilité, et me permet d'interfacer facilement avec d'autres choses Python.

La configuration de Jupyter a quelques parties mobiles, mais une fois que je l'ai fait fonctionner avec virtualenv, c'était incroyable.

Pour charger notre exécution CSV dans Jupyter:

import vaex
df = vaex.from_csv('10m.csv', names=['x', 'y', 'z'],)
df.plot_widget(df.x, df.y, backend='bqplot')

et nous pouvons voir instantanément:

enter image description here

Maintenant, nous pouvons zoomer, faire un panoramique et sélectionner des points avec la souris, et les mises à jour sont vraiment rapides. Ici, j'ai zoomé pour voir certains points individuels et en ai sélectionné quelques-uns (un léger rectangle plus léger sur l'image):

enter image description here

Une fois la sélection effectuée avec la souris, cela a exactement le même effet que l'utilisation de la méthode df.select(). Nous pouvons donc extraire les points sélectionnés en exécutant dans Jupyter:

df.to_pandas_df(selection=True)

qui produit des données au format:

        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

Puisque 10M points fonctionnaient bien, j'ai décidé d'essayer 1B points!

import vaex
df = vaex.open('1b.hdf5')
df.plot_widget(df.x, df.y, backend='bqplot')

Pour observer la valeur aberrante, qui était invisible sur le tracé d'origine, nous pouvons suivre Comment changer le style de point dans un vaex interactif Jupyter bqplot plot_widget pour rendre les points individuels plus grands et visibles? et utiliser:

df.plot_widget(df.x, df.y, f='log', shape=128, backend='bqplot')

qui produit:

enter image description here

et après avoir sélectionné le point:

enter image description here

nous obtenons les données complètes de la valeur aberrante:

   x          y           z
0  500000000  1500000000  -1

Existe-t-il un moyen de rendre ces points individuels plus visibles? Demandé à: Comment changer le style de point dans un vaex interactif Jupyter bqplot plot_widget pour rendre les points individuels plus grands et visibles?

Résultat: ça marche !!!! Le chargement initial prend environ 10 secondes, les zooms et la sélection de la souris environ 3 secondes chacun, et l'évaluation finale de la sélection également environ 10 secondes! Toutes les vitesses impressionnantes pour un ensemble de données aussi massif.

Voici une démo des créateurs avec un jeu de données plus intéressant et plus de fonctionnalités: https://www.youtube.com/watch?v=2Tt0i823-ec&t=77

Testé dans Ubuntu 19.04.

VisIt 2.13.3

Site Web: https://wci.llnl.gov/simulation/computer-codes/visit

Licence: BSD

Développé par Lawrence Livermore National Laboratory , qui est un laboratoire National Nuclear Security Administration , vous pouvez donc imaginer que des points de 10 m ne seront rien si je pouvais le faire fonctionner.

Installation: il n'y a pas de paquet Debian, il suffit de télécharger les binaires Linux depuis le site Web. Fonctionne sans installation. Voir aussi: https://askubuntu.com/questions/966901/installing-visit

Basé sur VTK qui est la bibliothèque backend que la plupart des logiciels de graphisme haute performance utilisent. Écrit en C.

Après 3 heures de jeu avec l'interface utilisateur, je l'ai fait fonctionner et cela a résolu mon cas d'utilisation comme détaillé sur: https://stats.stackexchange.com/questions/376361/how-to-find- the-sample-points-that-have-statistically-significant-large-outlier-r

Voici à quoi cela ressemble sur les données de test de ce post:

enter image description here

et un zoom avec quelques choix:

enter image description here

et voici la fenêtre des choix:

enter image description here

En termes de performances, VisIt était très bon: chaque opération graphique ne prenait que peu de temps ou était immédiate, et je pense qu'elle peut facilement gérer beaucoup plus de données. Quand j'ai dû attendre, il affiche un message de "traitement" avec le pourcentage de travail restant, et l'interface graphique ne s'est pas figée.

Étant donné que 10 millions de points fonctionnaient si bien, j'ai également essayé 100 millions de points (un fichier CSV 2,7 G), mais il s'est écrasé/est entré dans un état étrange, malheureusement, je l'ai regardé dans htop alors que les 4 threads VisIt occupaient tous mes 16GiB RAM et est décédé probablement en raison d'une panne de malloc.

Le démarrage initial a été un peu douloureux:

  • de nombreux défauts paraissent atroces si vous n'êtes pas ingénieur en bombe nucléaire? Par exemple.:
    • taille de point par défaut 1px (se confond avec la poussière sur mon moniteur)
    • échelle des axes de 0,0 à 1,0: Comment afficher les valeurs réelles du nombre d'axes sur le programme de tracé de visite au lieu des fractions de 0,0 à 1,0?
    • configuration multi-fenêtres, méchantes fenêtres contextuelles multiples lorsque vous choisissez des points de données
    • affiche votre nom d'utilisateur et la date du tracé (supprimer avec "Contrôles"> "Annotation"> "Informations utilisateur")
    • les valeurs par défaut du positionnement automatique sont mauvaises: la légende entre en conflit avec les axes, n'a pas pu trouver l'automatisation du titre, a donc dû ajouter une étiquette et tout repositionner à la main
  • il y a juste beaucoup de fonctionnalités, donc il peut être difficile de trouver ce que vous voulez
  • le manuel était très utile, mais c'est une page de 386 PDF mammouth daté de façon inquiétante "Octobre 2005 Version 1.5". Je me demande s'ils l'ont utilisé pour développer Trinity ! et c'est un Nice Sphinx HTML créé juste après avoir répondu à l'origine à cette question
  • aucun paquet Ubuntu. Mais les binaires préconstruits ont fonctionné.

J'attribue ces problèmes à:

  • il existe depuis si longtemps et utilise des idées GUI obsolètes
  • vous ne pouvez pas simplement cliquer sur les éléments du tracé pour les modifier (par exemple, les axes, le titre, etc.), et il y a beaucoup de fonctionnalités, il est donc un peu difficile de trouver celui que vous recherchez

J'aime aussi la façon dont un peu d'infrastructure LLNL s'infiltre dans ce dépôt. Voir par exemple docs/OfficeHours.txt et d'autres fichiers dans ce répertoire! Je suis désolé pour Brad qui est le "gars du lundi matin"! Oh, et le mot de passe du répondeur est "Kill Ed", n'oubliez pas cela.

Paraview 5.4.1

Site Web: https://www.paraview.org/

Licence: BSD

Installation:

Sudo apt-get install paraview

Développé par Sandia National Laboratories qui est un autre laboratoire de la NNSA, nous nous attendons donc à nouveau à ce qu'il gère facilement les données. Également basé sur VTK et écrit en C++, ce qui était encore plus prometteur.

Cependant, j'ai été déçu: pour une raison quelconque, 10 millions de points ont rendu l'interface graphique très lente et ne répond pas.

Je vais bien avec un moment contrôlé et bien annoncé "Je travaille maintenant, attendez un peu", mais l'interface graphique se bloque pendant que cela se produit? Pas acceptable.

htop a montré que Paraview utilisait 4 threads, mais ni le CPU ni la mémoire n'étaient au maximum.

Côté GUI, Paraview est très agréable et moderne, bien meilleur que VisIt quand il ne bégaie pas. Le voici avec un nombre de points inférieur pour référence:

enter image description here

et voici la feuille de calcul avec une sélection manuelle de points:

enter image description here

Un autre inconvénient est que Paraview ressentait un manque de fonctionnalités par rapport à VisIt, par exemple:

Mayavi 4.6.2

Site Web: https://github.com/enthought/mayavi

Développé par: Enthought

Installer:

Sudo apt-get install libvtk6-dev
python3 -m pip install -u mayavi PyQt5

Le VTK Python one.

Mayavi semble être très concentré sur la 3D, je n'ai pas trouvé comment y faire des tracés 2D, donc il ne le coupe malheureusement pas pour mon cas d'utilisation.

Pour vérifier les performances cependant, j'ai adapté l'exemple de: https://docs.enthought.com/mayavi/mayavi/auto/example_scatter_plot.html pour 10 millions de points, et il fonctionne très bien sans retard :

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()

Sortie:

enter image description here

Je n'ai cependant pas pu zoomer suffisamment pour voir des points individuels, le plan 3D proche était trop loin. Peut-être qu'il y a un moyen?

Une chose intéressante à propos de Mayavi est que les développeurs ont mis beaucoup d'efforts pour vous permettre de lancer et de configurer l'interface graphique à partir d'un script Python bien, tout comme Matplotlib et gnuplot. Il semble que cela soit également possible à Paraview, mais les documents ne sont pas aussi bons au moins.

En général, il ne semble pas être une fonctionnalité complète comme VisIt/Paraview. Par exemple, je n'ai pas pu charger directement un CSV depuis l'interface graphique: Comment charger un fichier CSV depuis l'interface graphique Mayavi?

Gnuplot 5.2.2

Site Web: http://www.gnuplot.info/

gnuplot est vraiment pratique quand j'ai besoin d'aller vite et sale, et c'est toujours la première chose que j'essaye.

Installation:

Sudo apt-get install gnuplot

Pour une utilisation non interactive, il peut gérer 10 m de points raisonnablement bien:

#!/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

qui s'est terminé en 7 secondes:

enter image description here

Mais si j'essaie de devenir interactif avec

#!/usr/bin/env gnuplot
set terminal wxt size 1024,1024
set key off
set datafile separator ","
plot "10m.csv" using 1:2:3 palette

et:

gnuplot -persist main.gnuplot

le rendu initial et les zooms semblent alors trop lents. Je ne vois même pas la ligne de sélection du rectangle!

Notez également que pour mon cas d'utilisation, j'avais besoin d'utiliser des étiquettes hypertextes comme dans:

plot "10m.csv" using 1:2:3 with labels hypertext

mais il y avait un bug de performance avec la fonctionnalité d'étiquettes, y compris pour le rendu non interactif. Mais je l'ai signalé et Ethan l'a résolu en une journée: https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/qpL8aJIi9ZE

Je dois cependant dire qu'il existe une solution de contournement raisonnable pour la sélection des valeurs aberrantes: ajoutez simplement des étiquettes avec l'ID de ligne à tous les points! S'il y a beaucoup de points à proximité, vous ne pourrez pas lire les étiquettes. Mais pour les valeurs aberrantes dont vous vous souciez, vous pourriez le faire! Par exemple, si j'ajoute une valeur aberrante à nos données d'origine:

cp 10m.csv 10m1.csv
printf '2500000,10000000,40000000\n' >> 10m1.csv

et modifiez la commande plot pour:

#!/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

Cela a considérablement ralenti le tracé (40 minutes après le correctif mentionné ci-dessus), mais produit une sortie raisonnable:

enter image description here

donc avec un peu de filtrage des données, on y arriverait finalement.

Matplotlib 1.5.1, numpy 1.11.1, Python 3.6.7

Site Web: https://matplotlib.org/

Matplotlib est ce que j'essaie habituellement lorsque mon script gnuplot commence à devenir trop fou.

numpy.loadtxt Seul a pris environ 10 secondes, donc je savais que ça n'allait pas bien se passer:

#!/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()

D'abord, la tentative non interactive a donné une bonne sortie, mais a pris 3 minutes et 55 secondes ...

L'interactif a ensuite mis beaucoup de temps sur le rendu initial et sur les zooms. Non utilisable:

enter image description here

Notez sur cette capture d'écran comment la sélection de zoom, qui devrait immédiatement zoomer et disparaître, est restée longtemps à l'écran pendant qu'elle attendait que le zoom soit calculé!

J'ai dû commenter plt.figure(figsize=(8, 8), dpi=128) pour que la version interactive fonctionne pour une raison quelconque, sinon elle a explosé avec:

RuntimeError: In set_size: Could not set the fontsize

Bokeh 1.3.1

https://github.com/bokeh/bokeh

Installation d'Ubuntu 19.04:

python3 -m pip install bokeh

Lancez ensuite Jupyter:

jupyter notebook

Maintenant, si je trace des points de 1 m, tout fonctionne parfaitement, l'interface est impressionnante et rapide, y compris le zoom et les informations de survol:

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)

Vue initiale:

enter image description here

Après un zoom:

enter image description here

Si je monte jusqu'à 10m bien qu'il s'étouffe, htop montre que le chrome a 8 threads occupant toute ma mémoire dans un état ininterruptible IO.

Cela demande de référencer les points: Comment référencer les points de données bokeh sélectionnés

PyViz https://pyviz.org/

TODO évaluer.

Intègre Bokeh + datahader + autres outils.

Démonstration vidéo des points de données 1B: https://www.youtube.com/watch?v=k27MJJLJNT4 "PyViz: Tableaux de bord pour visualiser 1 milliard de points de données dans 30 lignes de Python" par "Anaconda, Inc." publié le 2018-04-17.

Je suggérerais quelque chose d'un peu complexe, mais cela devrait fonctionner: créez votre graphique à différentes résolutions, pour différentes plages.

Pensez à Google Earth, par exemple. Si vous dézoomez au niveau maximum pour couvrir toute la planète, la résolution est la plus basse. Lorsque vous zoomez, les images changent pour des photos plus détaillées, mais uniquement sur la région sur laquelle vous zoomez.

Donc, fondamentalement pour votre tracé (est-ce 2D? 3D? Je suppose que c'est 2D), je vous suggère de construire un grand graphique qui couvre toute la plage [0, n] avec une faible résolution, 2 graphiques plus petits qui couvrent [0, n/2] et [n/2 + 1, n] avec deux fois la résolution du grand, 4 graphiques plus petits couvrant [0, n/4] ... [3 * n/4 + 1, n] avec deux fois la résolution des 2 ci-dessus, et ainsi de suite.

Je ne suis pas sûr que mon explication soit vraiment claire. De plus, je ne sais pas si ce type de graphique multi-résolution est géré par un programme de tracé existant.

7
user703016

Je me demande s'il y a une victoire à gagner en accélérant la recherche de vos points? (J'ai été intrigué par les arbres R * (r star) pendant un certain temps.)

Je me demande si l'utilisation de quelque chose comme un arbre r * dans ce cas pourrait être la voie à suivre. (lors d'un zoom arrière, des nœuds plus élevés dans l'arbre peuvent contenir des informations sur le rendu plus grossier et zoomé, les nœuds plus loin vers les feuilles contiennent les échantillons individuels)

peut-être même la mémoire mappe l'arborescence (ou la structure que vous finissez par utiliser) dans la mémoire pour maintenir vos performances et votre RAM utilisation faible. (vous déchargez la tâche de gestion de la mémoire sur le noyau)

espérons que cela a du sens .. divaguer un peu. il est tard!

1
nielsbot