Matplotlib = Benutzerfreundlichkeit, Gnuplot = (etwas bessere) Leistung
Ich weiß, dass dieser Beitrag alt ist und bereits beantwortet wurde, aber ich bin vorbeigekommen und wollte meinen Senf dazugeben. Hier ist meine Schlussfolgerung: Wenn Sie einen nicht so großen Datensatz haben, sollten Sie Matplotlib verwenden. Es ist einfacher und sieht besser aus. Wenn Sie jedoch wirklich Leistung benötigen, können Sie Gnuplot verwenden. Ich habe etwas Code hinzugefügt, mit dem Sie es auf Ihrem Rechner testen und selbst sehen können, ob es einen wirklichen Unterschied macht (dies ist kein echter Leistungsvergleich, sollte aber einen ersten Eindruck vermitteln).
Das folgende Diagramm zeigt die benötigte Zeit (in Sekunden), um:
- Zeichnen Sie ein zufälliges Streudiagramm
- Speichern Sie das Diagramm in einer png-Datei
Konfiguration:
- gnuplot: 5.2.2
- gnuplot-py: 1.8
- matplotlib: 2.1.2
Ich erinnere mich, dass der Leistungsunterschied auf einem älteren Computer mit älteren Versionen der Bibliotheken viel größer war (~30 Sekunden Unterschied bei einem großen Streudiagramm).
Außerdem können Sie, wie in den Kommentaren erwähnt, eine gleichwertige Qualität der Grundstücke erhalten. Allerdings muss man dafür mehr Schweiß aufwenden, um es mit Gnuplot zu schaffen.
Hier ist der Code zur Erstellung des Diagramms wenn Sie es auf Ihrem Rechner ausprobieren möchten:
# -*- coding: utf-8 -*-
from timeit import default_timer as timer
import matplotlib.pyplot as plt
import Gnuplot, Gnuplot.funcutils
import numpy as np
import sys
import os
def mPlotAndSave(x, y):
plt.scatter(x, y)
plt.savefig('mtmp.png')
plt.clf()
def gPlotAndSave(data, g):
g("set output 'gtmp.png'")
g.plot(data)
g("clear")
def cleanup():
try:
os.remove('gtmp.png')
except OSError:
pass
try:
os.remove('mtmp.png')
except OSError:
pass
begin = 2
end = 500000
step = 10000
numberOfPoints = range(begin, end, step)
n = len(numberOfPoints)
gnuplotTime = []
matplotlibTime = []
progressBarWidth = 30
# Init Gnuplot
g = Gnuplot.Gnuplot()
g("set terminal png size 640,480")
# Init matplotlib to avoid a peak in the beginning
plt.clf()
for idx, val in enumerate(numberOfPoints):
# Print a nice progress bar (crucial)
sys.stdout.write('\r')
progress = (idx+1)*progressBarWidth/n
bar = "" + ""*progress + ""*(progressBarWidth-progress) + "" + str(idx) + "/" + str(n-1)
sys.stdout.write(bar)
sys.stdout.flush()
# Generate random data
x = np.random.randint(sys.maxint, size=val)
y = np.random.randint(sys.maxint, size=val)
gdata = zip(x,y)
# Generate string call to a matplotlib plot and save, call it and save execution time
start = timer()
mPlotAndSave(x, y)
end = timer()
matplotlibTime.append(end - start)
# Generate string call to a gnuplot plot and save, call it and save execution time
start = timer()
gPlotAndSave(gdata, g)
end = timer()
gnuplotTime.append(end - start)
# Clean up the files
cleanup()
del g
sys.stdout.write('\n')
plt.plot(numberOfPoints, gnuplotTime, label="gnuplot")
plt.plot(numberOfPoints, matplotlibTime, label="matplotlib")
plt.legend(loc='upper right')
plt.xlabel('Number of points in the scatter graph')
plt.ylabel('Execution time (s)')
plt.savefig('execution.png')
plt.show()