2

I need to plot ~2000x300 lines within a single plot. e.g. something like that, but with 300 curves (each of 2000 datapoints) instead of four shown here: example plot

First I set up the figure:

fig, ax = plt.subplots(figsize=(8, 8))

Then I do the following for many times:

drawnLine = plt.Line2D([Xstart, Xfinish], [Ystart,Yfinish], 1, linestyle='solid', color='b')
ax.add_artist(drawnLine)

and in the end I wanted to do:

fig.savefig(ExpFolder + 'NewFig.png')

However the script reaches the 8GB memory limits and stops.

  • 2
    You really need all 2000 data-points? Smoothing or subsampling is not acceptable? – Steven Laan Aug 24 '17 at 08:14
  • 1
    You can surely try using a [`LineCollection`](https://matplotlib.org/examples/pylab_examples/line_collection2.html) instead of individual lines. This will be much more efficient. (If it is sufficient to get below the memory limit,however, I can't know) If you have problems with that, provide a [mcve] of the issue. – ImportanceOfBeingErnest Aug 24 '17 at 10:35

2 Answers2

0

Yeah, matplotlib isn't the most memory-efficient library in the world.

Now, 600,000 segments really is a lot if you do it in pure unadulterated naive software drawing so, hm, not cool.

What I'd propose is that you abandon matplotlib's canvas methods for either:

  • consider a fixed image size (in pixels), and directly render the lines onto that canvas. You can do that with some tricks for images that you show with matplotlib's imagesc and consorts, but really, you're not making your life easier at that point. So pick any python library that allows you to paint pixels onto a bitmap. There's some.
  • Consider something that doesn't try to draw 600,000 lines in software – I'm thinking of simply directly talking to your graphics hardware.
  • Simply use something less inefficient than matplotlib. I like pyqtgraph.

pyqtgraph example:

import pyqtgraph as pg
from PyQt4.QtGui import QApplication
import numpy
N=20
x = numpy.random.poisson(lam=0.01, size=(N,2000))
y = numpy.random.normal(size=(N,2000))
p = pg.plot()
for x_,y_ in zip(x,y):
    p.addItem(pg.PlotDataItem(x_,y_))
QApplication.instance().exec_()
Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • Thank you very much. I am actually having a problem to install PyQt4 for win_x64. Is it possible to replace this package with something? I am sorry for asking simple questions, I am having zero experience on python's graphics. – Petya Lidsky Aug 24 '17 at 14:41
  • @PetyaLidsky I've not used windows for a long time, but shouldn't the Windows amd64 installer from http://www.pyqtgraph.org/ be exactly what you need? – Marcus Müller Aug 25 '17 at 07:17
  • and for the pyqt4 / Q4 dependency, see https://stackoverflow.com/questions/22640640/how-to-install-pyqt4-on-windows-using-pip – Marcus Müller Aug 25 '17 at 07:18
0

Thanks to everybody. In the end the optimal solution was with use of matplotlib.collections as it was suggested by ImportanceOfBeingErnest. Image full