jamshid
jamshid

Reputation: 31

How to draw or plot large amount of points in c# repeatedly?

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

Answers (2)

oarrivi
oarrivi

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

Bloopy
Bloopy

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

Related Questions