Reputation: 31
I wanna draw or plot large amount of data points (almost 500,000 points) in Winform application repeatedly (every 10ms). I have used some common plotting controls but they can't handle this. They become too slow. My program does another jobs so it should be efficient.
Any suggestions? Thanks.
Upvotes: 1
Views: 2711
Reputation: 191
It makes no sense to draw such amount of points since the number of pixels in screen is much less.
I faced a similar problem time ago and I did the following process:
I reduce the number of data points to something more handy.
For example, I realised that I didn't need more than 1000 points because of the number of pixels. Actually the ideal number of points would be the canvas width. Then, I calculate the number of data points to draw per pixel. This is, if you have 500k data points, and your canvas is 1000 pixels, it means a pixel will draw 500 data points. You see, it makes no sense to draw 500 data points in a column of pixels...
Therefore, I split data points list in groups depending on the number of pixels. For example, for the first pixels I take the first 500 points, for the second pixel, next 500 data points, and so on.
To draw 500 data points in a column of pixels, basically I locate max and min values and draw a vertical line.
Hope this approach helps you.
Upvotes: 2
Reputation: 429
Windows Forms may not be a great choice for this, but I suppose you don't really know unless you try. This answer is a good place to start. I assigned a DirectBitmap
to a picture box:
_bitmap = new DirectBitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = _bitmap.Bitmap;
Then I created an array of 500,000 points which I'm continually updating with random data in another thread:
private const int _numPoints = 500000;
private static Point[] _points = new Point[_numPoints];
Now I clear the bitmap (to black) and draw the points by setting individual pixels. Call this every 10ms:
private void DrawPoints() {
Array.Clear(_bitmap.Bits, 0, _bitmap.Bits.Length);
int color = Color.Gray.ToArgb();
for (int i = 0; i < _numPoints; i++) {
int bmpIndex = _points[i].X + _points[i].Y * pictureBox1.Width;
_bitmap.Bits[bmpIndex] = color;
}
pictureBox1.Invalidate();
}
My PC is close to 5 years old and DrawPoints
is taking between 4 to 16ms to run. There are plenty more optimisations you could try such as using an 8-bit bitmap or updating parts of the bitmap from multiple threads.
Upvotes: 2