示例#1
0
        /// <summary>
        /// Draws a ternary plot from the passed data.
        /// Assumes that the passed matrix values are all normalised in [0,1].
        /// </summary>
        /// <param name="matrixDictionary">dicitonary of matrices - each matrix is one index.</param>
        /// <param name="keys">The names of the three indices/attributes. Also used as keys to dicitonary of matrices.</param>
        public static Image DrawTernaryPlot(Dictionary <string, double[, ]> matrixDictionary, string[] keys)
        {
            int    rowCount = matrixDictionary[keys[0]].GetLength(0);
            int    colCount = matrixDictionary[keys[0]].GetLength(1);
            int    scale    = 500;
            double factor   = Math.Sqrt(3.0) / 2.0;
            int    height   = (int)Math.Ceiling(500 * factor);
            var    histo1   = new double[scale + 1, scale + 1];
            var    histo2   = new double[scale + 1, scale + 1];
            var    histo3   = new double[scale + 1, scale + 1];

            double[] triplet = new double[3];
            string   label1  = "Ternary Plot: ";
            string   label2  = string.Empty;

            for (int r = 0; r < rowCount; r++)
            {
                for (int c = 0; c < colCount; c++)
                {
                    triplet[0] = matrixDictionary[keys[0]][r, c];
                    triplet[1] = matrixDictionary[keys[1]][r, c];
                    triplet[2] = matrixDictionary[keys[2]][r, c];
                    double tripletSum = triplet.Sum();

                    // ignore points with low values
                    if (tripletSum < 0.5)
                    {
                        continue;
                    }

                    triplet = DataTools.Normalise2Probabilites(triplet);

                    // for testing purposes
                    //triplet[0] = 0.0;
                    //triplet[1] = 0.0;
                    //triplet[2] = 0.95;

                    // in converting to ternary plot, a+b+c = 1.0 because triplet has already been normalised
                    double x      = triplet[0] * factor;
                    double y      = (triplet[0] + (2 * triplet[1])) / 2;
                    int    xCoord = scale - (int)Math.Round(x * scale);
                    int    yCoord = scale - (int)Math.Round(y * scale);

                    //int yCoord = (int)Math.Round(y * scale);

                    // time of day
                    if (r < 360 || r > 1053)
                    {
                        histo3[xCoord, yCoord]++; // night blue
                    }
                    else
                    if (r > 360 && r < 480)
                    {
                        histo1[xCoord, yCoord]++; // morning chorus red
                    }
                    else
                    {
                        histo2[xCoord, yCoord]++;
                    }

                    label2 = "Time of Day >> RGB=(dawnChorus, day, night)";

                    // frequency band
                    //if (c > 128) histo3[xCoord, yCoord]++; // high frequency
                    //else
                    //if (c > 32) histo2[xCoord, yCoord]++; // mid frequency
                    //else histo1[xCoord, yCoord]++; // low frequency
                    //label2 = "Freq Band >> RGB=(low, mid, hi)";

                    // sum of index values
                    //if (tripletSum > 1.2) histo1[xCoord, yCoord]++;
                    //else
                    //if (tripletSum > 0.6) histo2[xCoord, yCoord]++;
                    //else                  histo3[xCoord, yCoord]++;
                    //label2 = "Index Sum >> RGB=(hi, mid, low)";
                }
            }

            //histo = MatrixTools.Matrix2LogValues(histo);
            //histo = MatrixTools.SquareRootOfValues(histo);
            histo1          = MatrixTools.LogTransform(histo1);
            histo2          = MatrixTools.LogTransform(histo2);
            histo3          = MatrixTools.LogTransform(histo3);
            double[,] norm1 = DataTools.normalise(histo1);
            double[,] norm2 = DataTools.normalise(histo2);
            double[,] norm3 = DataTools.normalise(histo3);
            var stringFont = Drawing.Arial12;

            //Image bmp = ImageTools.DrawMatrixWithoutNormalisationGreenScale(norm);
            var bmp = ImageTools.DrawRGBMatrix(norm1, norm2, norm3); // RGB

            bmp.Mutate(g =>
            {
                int halfWidth = scale / 2;

                // draw plot outline
                g.DrawLine(new Pen(Color.White, 1), 0, scale, halfWidth, scale - height);
                g.DrawLine(new Pen(Color.White, 1), scale, scale, halfWidth, scale - height);

                //label vertices
                g.DrawText(keys[0], stringFont, Color.Wheat, new PointF(halfWidth - 15, scale - height - 15));
                g.DrawText(keys[1], stringFont, Color.Wheat, new PointF(0, scale - 20));
                g.DrawText(keys[2], stringFont, Color.Wheat, new PointF(scale - 40, scale - 20));

                // draw label
                string label = label1 + label2;
                g.DrawText(label, stringFont, Color.Wheat, new PointF(30, scale - height - 40));
            });
            return(bmp);
        }