protected void PaintOnGraphicsBitmap(IGraphics g, int width, int height)
 {
     if (backBuffer == null || scatterPlot == null) {
         return;
     }
     UnsafeBitmap copyBackBuffer = new UnsafeBitmap(backBuffer);
     copyBackBuffer.LockBitmap();
     // selected data-points
     foreach (int s in scatterPlot.Selection) {
         double[] w = scatterPlot.GetDataAt(s);
         if (w.Length > 0){
             double x = w[0];
             double y = w[1];
             SymbolProperties gx = GetPointProperties != null ? GetPointProperties(s) : defaultSymbol;
             SymbolType symbolType = SymbolType.allSymbols[gx.Type];
             int symbolSize = gx.Size;
             if (symbolSize > 0){
                 int[] pathX;
                 int[] pathY;
                 symbolType.GetPath(symbolSize, out pathX, out pathY);
                 copyBackBuffer.DrawPath(SelectionColor, ModelToViewX(x, width), ModelToViewY(y, height), pathX, pathY);
             }
         }
     }
     copyBackBuffer.UnlockBitmap();
     // labels
     ScatterPlotLabelMode labelMode = scatterPlot.GetLabelMode();
     bool cutLabels = scatterPlot.CutLabels;
     if (labelMode == ScatterPlotLabelMode.All && scatterPlot.HasLabels) {
         Font font = new Font("Arial", scatterPlot.FontSize, scatterPlot.FontStyle);
         for (;;){
             double[] x;
             double[] y;
             double[] z;
             string[] labels;
             int index;
             try{
                 scatterPlot.GetData(out x, out y, out z, out labels, out index);
             } catch (IndexOutOfRangeException){
                 break;
             }
             if (x == null){
                 break;
             }
             SymbolProperties gx = GetPointProperties != null ? GetPointProperties(index) : defaultSymbol;
             for (int i = 0; i < x.Length; i++){
                 if (labelMode == ScatterPlotLabelMode.All || scatterPlot.IsSelected(i)) {
                     int ix = ModelToViewX(x[i], width);
                     int iy = ModelToViewY(y[i], height);
                     Color c;
                     if (z != null && colorScale != null){
                         c = colorScale.GetColor(z[i]);
                     } else{
                         c = gx.Color;
                     }
                     Brush b = new SolidBrush(c);
                     if (ix >= 0 && iy >= 0 && ix < width && iy < height){
                         if (labels[i] != null){
                             string s = labels[i];
                             if (cutLabels){
                                 if (s.Contains(";")){
                                     s = s.Substring(0, s.IndexOf(';'));
                                 }
                             }
                             copyBackBuffer.DrawString(s, font, b, ix, iy);
                         }
                     }
                 }
             }
         }
         scatterPlot.Reset();
     }
     if (labelMode == ScatterPlotLabelMode.Selected && scatterPlot.HasLabels) {
         Brush br = new SolidBrush(SelectionColor);
         Font font = new Font("Arial", scatterPlot.FontSize, scatterPlot.FontStyle);
         foreach (int s in scatterPlot.Selection) {
             double[] w = scatterPlot.GetDataAt(s);
             string label = scatterPlot.GetLabelAt(s);
             double x = w[0];
             double y = w[1];
             int ix = ModelToViewX(x, width);
             int iy = ModelToViewY(y, height);
             if (ix >= 0 && iy >= 0 && ix < width && iy < height){
                 if (label != null){
                     if (cutLabels){
                         if (label.Contains(";")){
                             label = label.Substring(0, label.IndexOf(';'));
                         }
                     }
                     copyBackBuffer.DrawString(label, font, br, ix, iy);
                 }
             }
         }
     }
     // draw the image
     g.DrawImageUnscaled(copyBackBuffer.Bitmap, 0, 0);
     copyBackBuffer.Dispose();
     g.SmoothingMode = SmoothingMode.AntiAlias;
     DrawPolygons(g, width, height);
     if (drawFunctions != null){
         drawFunctions(g, width, height, ModelToViewX, ModelToViewY, ViewToModelX, ViewToModelY);
     }
     g.SmoothingMode = SmoothingMode.Default;
 }