Beispiel #1
0
        private static MCharting.Series GetOrCreateSeriesForValue(MCharting.Plot plot, Column column, Visualisable vis, ref bool isGroup)
        {
            object value = column.GetRow(vis);

            MCharting.Series series = plot.Series.FirstOrDefault(z => (z.Tag == null && value == null) || (z.Tag != null && z.Tag.Equals(value)));

            if (series == null)
            {
                series      = new MCharting.Series();
                series.Name = Column.AsString(value, column.DisplayMode);
                series.Tag  = value;

                if (value is GroupInfoBase)
                {
                    GroupInfoBase group = (GroupInfoBase)value;
                    UiControls.CreateIcon(series, group);
                    isGroup = true;
                }
                else
                {
                    series.Style.DrawPoints = new SolidBrush(column.GetColour(vis));
                }

                plot.Series.Add(series);
            }

            return(series);
        }
Beispiel #2
0
        protected Dictionary <GroupInfoBase, MCharting.Series> DrawLegend(MCharting.Plot plot, IEnumerable <GroupInfoBase> viewTypes)
        {
            Dictionary <GroupInfoBase, MCharting.Series> result = new Dictionary <GroupInfoBase, MCharting.Series>();

            foreach (GroupInfoBase group in viewTypes)
            {
                MCharting.Series legendEntry = new MCharting.Series();
                legendEntry.Name             = group.DisplayName;
                legendEntry.Style.DrawVBands = new SolidBrush(group.Colour);
                plot.LegendEntries.Add(legendEntry);
                result.Add(group, legendEntry);
            }

            return(result);
        }
Beispiel #3
0
        private void UpdatePlot()
        {
            if (this._scores == null)
            {
                this._lblSelection.Text      = this._errorMessage;
                this._lblSelection.ForeColor = Color.Red;
                this._chart.Visible          = false;
                return;
            }

            this._chart.Visible          = true;
            this._lblSelection.Text      = "";
            this._lblSelection.ForeColor = ForeColor;

            MCharting.Plot plot = new MCharting.Plot();

            plot.Title    = $"{this._lblMethod.Text} of {this._core.FileNames.Title}";
            plot.SubTitle = $"Source: {this._lblPcaSource.Text}, View: {this._lblPlotView.Text}, Legend: {this._lblLegend.Text}, Corrections: {this._lblCorrections.Text}, Observations: {this._lblObs.Text}, Peaks: {this._lblPeaks.Text}";

            switch (this._method)
            {
            case EMethod.Pca:
                plot.XLabel = $"PC{this._component + 1}";
                plot.YLabel = $"PC{this._component + 2}";
                break;

            case EMethod.Plsr:
                plot.XLabel    = $"Component {this._component + 1}";
                plot.YLabel    = $"Component {this._component + 2}";
                plot.SubTitle += ", PLSR Response: " + this._lblPlsrSource.Text;
                break;
            }

            this._chart.Style.Margin = new Padding(48, 48, 48, 48);
            plot.Style.GridStyle     = new Pen(Color.FromArgb(224, 224, 224));

            // Get the "rows"
            IEnumerator enSources;
            Column      column;

            this.GetSource(this._colourBy, out enSources, out column);

            // Get the "columns"
            double[,] plotPoints;

            if (this._plotSource == EPlotSource.Loadings)
            {
                plotPoints = this._loadings;
            }
            else
            {
                plotPoints = this._scores;
            }

            // Get the component
            if (this._component < 0)
            {
                this._component = 0;
            }

            if (this._component >= plotPoints.GetLength(1))
            {
                this._component = plotPoints.GetLength(1) - 1;
            }

            this._btnPrevPc.Enabled = this._component != 0;
            this._btnNextPc.Enabled = this._component != plotPoints.GetLength(1) - 1;

            this._lblPlotView.Text    = this._plotSource == EPlotSource.Loadings ? "Loadings" : "Scores";
            this._btnScores.Checked   = this._plotSource == EPlotSource.Scores;
            this._btnLoadings.Checked = this._plotSource == EPlotSource.Loadings;

            this._lblPcNumber.Text = "PC" + (this._component + 1).ToString() + " / " + plotPoints.GetLength(1);

            this._lblLegend.Text = column.DisplayName;

            bool isGroup = false;

            // Iterate scores
            for (int r = 0; r < plotPoints.GetLength(0); r++)
            {
                enSources.MoveNext();

                MCharting.Series series = GetOrCreateSeriesForValue(plot, column, (Visualisable)enSources.Current, ref isGroup);

                var coord = new MCharting.DataPoint(plotPoints[r, this._component], plotPoints[r, this._component + 1]);
                coord.Tag = enSources.Current;

                series.Points.Add(coord);
            }

            // Assign colours
            if (!column.HasColourSupport && !isGroup)
            {
                foreach (var colour in PlotCreator.AutoColour(plot.Series))
                {
                    colour.Key.Style.DrawPoints = new SolidBrush(colour.Value);
                }
            }

            this._chart.Style.Animate         = true;
            this._chart.Style.SelectionColour = Color.Yellow;

            this._chart.SetPlot(plot);
        }
        /// <summary>
        /// Returns the series for a group and vector, creating one if it doesn't already exist
        /// </summary>
        /// <param name="plot">Plot to create series in</param>
        /// <param name="existingSeries">Existing series</param>
        /// <param name="group">Group to create series for</param>
        /// <param name="vector">Vector to create series for</param>
        /// <param name="style">Styles (colours and highlights)</param>
        /// <param name="groupLegends">Where to add legends to</param>
        /// <param name="lineLegend">Where to add legends to</param>
        /// <returns>Series (new or existing)</returns>
        private MCharting.Series GetOrCreateSeries(
            MCharting.Plot plot,
            Dictionary <GroupInfo, MCharting.Series> existingSeries,
            GroupInfo group,
            Vector vector,
            StylisedCluster style,
            Dictionary <GroupInfoBase, MCharting.Series> groupLegends,
            MCharting.Series lineLegend,
            HashSet <MCharting.Series> toBringToFront,
            bool bandw)
        {
            MCharting.Series series;

            if (existingSeries.TryGetValue(group, out series))
            {
                return(series);
            }

            Peak peak = vector.Peak;
            Dictionary <Peak, LineInfo> colours = style?.Colours;

            // Each peak + condition gets its own series (yes we end up with lots of series)
            series = new MCharting.Series();
            series.Style.StrictOrder = SeriesStyle.EOrder.X;
            series.Name = vector.ToString() + " : " + group.DisplayName;
            series.ApplicableLegends.Add(groupLegends[group]);
            series.ApplicableLegends.Add(lineLegend);
            plot.Series.Add(series);

            // If the parameters specify a colour for this peak use that, else use the default
            if (colours != null && colours.ContainsKey(peak))
            {
                series.Style.DrawLines           = new Pen(colours[peak].Colour, this._core.Options.LineWidth);
                series.Style.DrawLines.DashStyle = colours[peak].DashStyle;
                series.Name = colours[peak].SeriesName + " : " + group.DisplayName;
            }
            else
            {
                series.Style.DrawLines = new Pen(group.Colour, this._core.Options.LineWidth);
            }

            if (bandw)
            {
                series.Style.DrawLines = new Pen(this._core.Options.Colours.InputVectorJoiners, this._core.Options.LineWidth);
            }

            series.Style.DrawLines.Width = this._core.Options.LineWidth;
            series.Tag = peak;

            if (style.Highlight != null && !bandw)
            {
                foreach (StylisedCluster.HighlightElement highlight in style.Highlight)
                {
                    if (highlight.Peak == vector.Peak &&
                        (highlight.Group == null || highlight.Group == group))
                    {
                        series.Style.DrawLines.Color = this._core.Options.Colours.NotableHighlight;
                        series.Style.DrawLines.Width = this._core.Options.LineWidth * 2;
                        toBringToFront.Add(series);
                        break;
                    }
                }
            }

            existingSeries.Add(group, series);

            return(series);
        }
        /// <summary>
        /// Actual plotting.
        /// </summary>
        public void Plot(StylisedCluster stylisedCluster)
        {
            Debug.WriteLine("ClusterPlot: " + stylisedCluster);

            // Reset the chart
            bool    isPreview = stylisedCluster != null && stylisedCluster.IsPreview;
            Cluster p         = stylisedCluster != null ? stylisedCluster.Cluster : null;
            Plot    plot      = this.PrepareNewPlot(!isPreview, (stylisedCluster != null) ? stylisedCluster.Cluster : null, p?.Assignments.Vectors.FirstOrDefault()?.Source);

            // Set the selected cluster
            Dictionary <Peak, LineInfo> colours = stylisedCluster != null ? stylisedCluster.Colours : null;

            this.SelectedCluster = stylisedCluster;

            if (stylisedCluster != null)
            {
                this.SetCaption(stylisedCluster.CaptionFormat, stylisedCluster.ActualElement, stylisedCluster.WhatIsHighlighted);
            }
            else
            {
                this.SetCaption("No plot displayed.");
            }

            Core core = this._core;
            CoreColourSettings colourSettings = core.Options.Colours;

            // If there is nothing to plot then exit
            if (p == null)
            {
                this.CompleteNewPlot(plot);
                return;
            }

            // Sort the variables exemplars top-most
            List <Assignment> toPlot = new List <Assignment>(p.Assignments.List);

            // Too much to plot
            while (toPlot.Count > core.Options.MaxPlotVariables)
            {
                //toPlot = toPlot.OrderBy(z => z.Peak.Index).ToList();
                toPlot.RemoveRange(core.Options.MaxPlotVariables, toPlot.Count - core.Options.MaxPlotVariables);
            }

            int numClusterCentres            = 0;
            HashSet <GroupInfo> groupsInPlot = p.Assignments.Vectors.First().ColHeaders.Unique(z => z.Observation.Group);

            if (!this._core.Options.DisplayAllGroupsInClusterPlot)
            {
                groupsInPlot.RemoveWhere(z => !this._core.Options.ViewTypes.Contains(z));
            }

            GroupInfo[] groupOrder = groupsInPlot.OrderBy(GroupInfoBase.GroupOrderBy).ToArray();

            MCharting.Series legendEntry = new MCharting.Series();
            legendEntry.Name            = "Input vector";
            legendEntry.Style.DrawLines = new Pen(Color.Black, this._core.Options.LineWidth * 2);
            plot.LegendEntries.Add(legendEntry);

            // --- LEGEND ---
            var groupLegends = this.DrawLegend(plot, groupOrder);

            HashSet <MCharting.Series> toBringToFront = new HashSet <MCharting.Series>();

            // --- PLOT CLUSTER ASSIGNMENTS ---
            // Iterate variables in cluster
            for (int assignmentIndex = 0; assignmentIndex < toPlot.Count; assignmentIndex++)
            {
                Assignment assignment = toPlot[assignmentIndex];
                Vector     vec        = assignment.Vector;
                Peak       peak       = vec.Peak;
                Dictionary <GroupInfo, MCharting.Series> vecSeries  = new Dictionary <GroupInfo, MCharting.Series>();
                Dictionary <GroupInfo, MCharting.Series> vec2Series = new Dictionary <GroupInfo, MCharting.Series>();
                MCharting.DataPoint lastPoint  = null;
                MCharting.Series    lastSeries = null;

                ///////////////////
                // PLOT THE POINT
                // Okay! Now plot the values pertinent to this peak & type
                for (int i = 0; i < vec.Count; ++i)
                {
                    // Peak, by observation
                    ObservationInfo obs   = vec.Observations[i];
                    GroupInfo       group = obs.Group;

                    if (!groupOrder.Contains(group))
                    {
                        continue;
                    }

                    MCharting.Series series = this.GetOrCreateSeries(plot, vecSeries, group, vec, stylisedCluster, groupLegends, legendEntry, toBringToFront, false);

                    // When the series changes we create an intermediate series to join the two together
                    //MCharting.Series seriesb = null;

                    //if (series != lastSeries && lastSeries != null)
                    //{
                    //    seriesb = GetOrCreateSeries(plot, vec2Series, group, vec, stylisedCluster, groupLegends, legendEntry, toBringToFront, true);
                    //}

                    lastSeries = series;

                    int typeOffset = this.GetTypeOffset(groupOrder, group);

                    int    x = typeOffset + obs.Time;
                    double v = vec.Values[i];
                    MCharting.DataPoint dataPoint = new MCharting.DataPoint(x, v);
                    dataPoint.Tag = new IntensityInfo(obs.Time, obs.Rep, obs.Group, v);
                    series.Points.Add(dataPoint);

                    //if (seriesb != null)
                    //{
                    //    seriesb.Points.Add(lastPoint);
                    //    seriesb.Points.Add(dataPoint);
                    //}

                    lastPoint = dataPoint;
                }
            }

            // --- PLOT CLUSTER CENTRES ---
            if (!isPreview && core.Options.ShowCentres && p.Centres.Count != 0 && p.Centres.Count < 100)
            {
                MCharting.Series legendEntry2 = new MCharting.Series();
                legendEntry2.Name                      = (p.Centres.Count == 1) ? "Cluster centre" : "Cluster centres";
                legendEntry2.Style.DrawLines           = new Pen(colourSettings.ClusterCentre, this._core.Options.LineWidth * 2);
                legendEntry2.Style.DrawLines.DashStyle = DashStyle.Dash;
                legendEntry2.Style.DrawPoints          = new SolidBrush(colourSettings.ClusterCentre);
                legendEntry2.Style.DrawPointsSize      = 8; // MarkerStyle.Diamond;
                plot.LegendEntries.Add(legendEntry2);

                var templateAssignment = p.Assignments.List.First();

                foreach (double[] centre in p.Centres)
                {
                    MCharting.Series series = new MCharting.Series();
                    series.Style.StrictOrder = SeriesStyle.EOrder.X;
                    series.ApplicableLegends.Add(legendEntry2);
                    plot.Series.Add(series);
                    series.Name                      = "Cluster centre #" + (++numClusterCentres);
                    series.Style.DrawLines           = new Pen(colourSettings.ClusterCentre, this._core.Options.LineWidth * 2);
                    series.Style.DrawLines.DashStyle = DashStyle.Dash;
                    series.Style.DrawPoints          = new SolidBrush(colourSettings.ClusterCentre);
                    series.Style.DrawPointsSize      = 8; // MarkerStyle.Diamond;

                    IEnumerable <int> order = templateAssignment.Vector.Observations.WhichOrder(ObservationInfo.GroupTimeReplicateDisplayOrder);

                    foreach (int index in order)
                    {
                        // Centre, by observation
                        ObservationInfo cond = templateAssignment.Vector.Observations[index];

                        if (!groupOrder.Contains(cond.Group))
                        {
                            continue;
                        }

                        double dp = centre[index];
                        int    x  = this.GetTypeOffset(groupOrder, cond.Group) + cond.Time;
                        MCharting.DataPoint cdp = new MCharting.DataPoint(x, dp);
                        cdp.Tag = new IntensityInfo(cond.Time, cond.Rep, cond.Group, dp);
                        series.Points.Add(cdp);
                    }
                }
            }

            // Bring highlighted series to the front
            foreach (MCharting.Series series in toBringToFront)
            {
                plot.Series.Remove(series);
                plot.Series.Add(series);
            }

            // --- LABELS ---
            this.DrawLabels(plot, true, groupOrder, true);

            // --- COMPLETE ---
            this.CompleteNewPlot(plot);
        }