Rendering a heat map for 400.000 points I am trying to draw a heat map with a given input of points and amplitude of each point. The normal input size is around 400000 points, but the code draws every 15th point. The map is drawn onto a Canvas.

In the XAML:

&lt;Grid x:Name="MainPanel" Width="800" Height="600"&gt;
    &lt;Textbox Name="textbox" Grid.Column="0"/&gt;
    &lt;Canvas Name="canvas" Grid.Column="1" HorizontalAlignment="Left" Height="450" Margin="70,75,0,0" VerticalAlignment="Top" Width="706"/&gt;
&lt;/Grid&gt;


Rendering code:

public static void DrawPoints(Parser parser, Canvas canvas, double radiusX, double radiusY, double thickness, double minAmplitude, double maxAmplitude)
        {
            double cellWidth = canvas.ActualWidth;
            double cellHeight = canvas.ActualHeight;

            var list = parser.Data;

            // Draws every 15th point
            int res = 15;

            for (int i = 0; i &lt; list.Count; i += res)
            {
                var location = list[i].Point;
                var amplitude = list[i].Amplitude;

                // Converts rgb to hsv values for representation
                var color= ColorConverter.hsv2rgb(
                    COLOR_START_H * (1.0 - ((amplitude - minAmplitude) / (maxAmplitude - minAmplitude))),
                    COLOR_START_S, COLOR_START_V);

                Point center = new Point(location.X, location.Y);
                DrawEllipse(canvas, center, radiusX, radiusY,
                    new SolidColorBrush(color), new SolidColorBrush(color), thickness);
            }
            return;
        }


In the DrawEllipse() function:

public static void DrawEllipse(Canvas canvas, Point center, double radiusX, double radiusY, Brush fill, Brush stroke, double thickness)
        {
            var ellipse = new Ellipse();
            ellipse.Width = radiusX * 2;
            ellipse.Height = radiusY * 2;
            ellipse.Fill = fill;
            ellipse.Stroke = stroke;
            ellipse.StrokeThickness = thickness;

            Canvas.SetLeft(ellipse, center.X - radiusX);
            Canvas.SetBottom(ellipse, center.Y - radiusY);

            canvas.Children.Add(ellipse);

            return;
        }


In the Main code:

private void btnDraw_Click(object sender, RoutedEventArgs e)
{
    Painter.DrawPoints(parser, canvas, 3, 3, 1, 0, 100);
}


The issue is that after rendering all the points onto Canvas, when I try to enter some text into textbox within the same grid, there is significant lag. What can I do to reduce the lag?
Unless you need some sort of high level interaction with those points, to create 400,000 shapes (which are FrameworkElement, all but lightweight) is a waste of time and resources.

Did you consider to use an image, drawing them inside a WriteableImage and to display the image instead? Check MSDN for DrawingVisual and DrawingContext subjects. I used this method for small multiples composed with really huge heatmaps and it worked like a charm. Simple hittesting (for example to show a tooltip with exact value) is trivial to implement using X-Y coordinates.

You will keep your visual tree almost empty, you won't create few thousands brushes each time (but you can create your color palette once and use it multiple times) and redrawing will be as fast as you want. In most applications you don't need an infinite number of color shades, consider to limit palette to 256 entries and to map values to those discrete values. 

You will need to create an image with the proper size but this has a great advantage:


When redrawing is requested then immediately create a very low-res image with few hundred points. 
Start a background thread to draw the full-resolution image (using current canvas size).
When image is ready then simply replace the old low-res one.


In this way you can even easily debounce multiple requests caused by resize operations (if you care at all).

Note: to pick one point every N is not a proper decimation method because it doesn't preserve local minimum and maximum; you may (will!) visualize wrong results. Consider using minmax or, only if your type of data allows it, at least an average.