Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataPreprocessing Enhancements/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.cs @ 14521

Last change on this file since 14521 was 14521, checked in by pfleck, 7 years ago

#2709 Added an option for the preprocessing scatterplot to use a color gradient instead of the chart color palette.

File size: 11.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using HeuristicLab.Analysis;
27using HeuristicLab.Common;
28using HeuristicLab.Core.Views;
29using HeuristicLab.MainForm;
30using HeuristicLab.MainForm.WindowsForms;
31using RegressionType = HeuristicLab.Analysis.ScatterPlotDataRowVisualProperties.ScatterPlotDataRowRegressionType;
32
33namespace HeuristicLab.DataPreprocessing.Views {
34
35  [View("Scatter Plot Single View")]
36  [Content(typeof(SingleScatterPlotContent), true)]
37  public partial class ScatterPlotSingleView : ItemView {
38
39    private readonly string NoGroupItem = "-";
40
41    public new SingleScatterPlotContent Content {
42      get { return (SingleScatterPlotContent)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public ScatterPlotSingleView() {
47      InitializeComponent();
48
49      regressionTypeComboBox.DataSource = Enum.GetValues(typeof(RegressionType));
50      regressionTypeComboBox.SelectedItem = RegressionType.None;
51    }
52
53    public void InitData() {
54      IEnumerable<string> variables = Content.PreprocessingData.GetDoubleVariableNames();
55
56      // add variables to combo boxes
57      comboBoxXVariable.Items.Clear();
58      comboBoxYVariable.Items.Clear();
59      comboBoxGroup.Items.Clear();
60      comboBoxXVariable.Items.AddRange(variables.ToArray());
61      comboBoxYVariable.Items.AddRange(variables.ToArray());
62      comboBoxGroup.Items.Add(NoGroupItem);
63      for (int i = 0; i < Content.PreprocessingData.Columns; ++i) {
64        if (Content.PreprocessingData.VariableHasType<double>(i)) {
65          //double distinctValueCount = Content.PreprocessingData.GetValues<double>(i).GroupBy(x => x).Count();
66          //if (distinctValueCount <= 20)
67          comboBoxGroup.Items.Add(Content.PreprocessingData.GetVariableName(i));
68        }
69      }
70
71      // use x and y variable from content
72      if (Content.SelectedXVariable != null && Content.SelectedYVariable != null && Content.SelectedGroupVariable != null) {
73        comboBoxXVariable.SelectedItem = Content.SelectedXVariable;
74        comboBoxYVariable.SelectedItem = Content.SelectedYVariable;
75        comboBoxGroup.SelectedItem = Content.SelectedGroupVariable;
76      } else {
77        if (variables.Count() >= 2) {
78          comboBoxXVariable.SelectedIndex = 0;
79          comboBoxYVariable.SelectedIndex = 1;
80          comboBoxGroup.SelectedIndex = 0;
81          UpdateScatterPlot();
82        }
83      }
84    }
85
86    protected override void OnContentChanged() {
87      base.OnContentChanged();
88      if (Content != null) {
89        InitData();
90      }
91    }
92
93    protected override void SetEnabledStateOfControls() {
94      base.SetEnabledStateOfControls();
95      useGradientCheckBox.Enabled = (string)comboBoxGroup.SelectedItem != NoGroupItem;
96      gradientPanel.Visible = useGradientCheckBox.Enabled && useGradientCheckBox.Checked; ;
97    }
98
99    private void UpdateScatterPlot() {
100      if (comboBoxXVariable.SelectedItem != null && comboBoxYVariable.SelectedItem != null && comboBoxGroup.SelectedItem != null) {
101        var xVariable = (string)comboBoxXVariable.SelectedItem;
102        var yVariable = (string)comboBoxYVariable.SelectedItem;
103        var groupVariable = (string)comboBoxGroup.SelectedItem;
104
105        bool groupingActive = useGradientCheckBox.Checked && groupVariable != NoGroupItem;
106        double min = 0, max = 1;
107        if (groupingActive) {
108          var groupValues = Content.PreprocessingData.GetValues<double>(Content.PreprocessingData.GetColumnIndex(groupVariable))
109            .Distinct().OrderBy(x => x).ToList();
110          min = groupValues.First();
111          max = groupValues.Last();
112        }
113        ScatterPlot scatterPlot = Content.CreateScatterPlot(xVariable, yVariable, groupVariable);
114        var rows = scatterPlot.Rows.ToList();
115        scatterPlot.Rows.Clear();
116        var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
117        int order = (int)polynomialRegressionOrderNumericUpDown.Value;
118        foreach (var row in rows) {
119          row.VisualProperties.PointSize = 6;
120          row.VisualProperties.IsRegressionVisibleInLegend = false;
121          row.VisualProperties.RegressionType = regressionType;
122          row.VisualProperties.PolynomialRegressionOrder = order;
123          row.VisualProperties.IsVisibleInLegend = !useGradientCheckBox.Checked;
124          if (groupingActive)
125            row.VisualProperties.Color = GetColor(double.Parse(row.Name), min, max);
126        }
127        scatterPlot.Rows.AddRange(rows);
128        var vp = scatterPlot.VisualProperties;
129        vp.Title = string.Empty;
130        vp.XAxisTitle = xVariable;
131        vp.YAxisTitle = yVariable;
132
133        scatterPlotControl.Content = scatterPlot;
134
135        if (groupingActive) {
136          gradientMinimumLabel.Text = min.ToString("G5");
137          gradientMaximumLabel.Text = max.ToString("G5");
138        }
139
140        //save selected x and y variable in content
141        this.Content.SelectedXVariable = (string)comboBoxXVariable.SelectedItem;
142        this.Content.SelectedYVariable = (string)comboBoxYVariable.SelectedItem;
143        this.Content.SelectedGroupVariable = (string)comboBoxGroup.SelectedItem;
144      }
145    }
146
147    private void comboBoxXVariable_SelectedIndexChanged(object sender, EventArgs e) {
148      var oldPlot = scatterPlotControl.Content;
149      UpdateScatterPlot();
150      var newPlot = scatterPlotControl.Content;
151
152
153      if (oldPlot == null || newPlot == null) return;
154      newPlot.VisualProperties.YAxisMinimumAuto = oldPlot.VisualProperties.YAxisMinimumAuto;
155      newPlot.VisualProperties.YAxisMaximumAuto = oldPlot.VisualProperties.YAxisMaximumAuto;
156      newPlot.VisualProperties.YAxisMinimumFixedValue = oldPlot.VisualProperties.YAxisMinimumFixedValue;
157      newPlot.VisualProperties.YAxisMaximumFixedValue = oldPlot.VisualProperties.YAxisMaximumFixedValue;
158
159      foreach (var x in newPlot.Rows.Zip(oldPlot.Rows, (nr, or) => new { nr, or })) {
160        var newVisuapProperties = (ScatterPlotDataRowVisualProperties)x.or.VisualProperties.Clone();
161        newVisuapProperties.DisplayName = x.nr.VisualProperties.DisplayName;
162        x.nr.VisualProperties = newVisuapProperties;
163      }
164    }
165
166    private void comboBoxYVariable_SelectedIndexChanged(object sender, EventArgs e) {
167      var oldPlot = scatterPlotControl.Content;
168      UpdateScatterPlot();
169      var newPlot = scatterPlotControl.Content;
170
171      if (oldPlot == null || newPlot == null) return;
172      newPlot.VisualProperties.XAxisMinimumAuto = oldPlot.VisualProperties.XAxisMinimumAuto;
173      newPlot.VisualProperties.XAxisMaximumAuto = oldPlot.VisualProperties.XAxisMaximumAuto;
174      newPlot.VisualProperties.XAxisMinimumFixedValue = oldPlot.VisualProperties.XAxisMinimumFixedValue;
175      newPlot.VisualProperties.XAxisMaximumFixedValue = oldPlot.VisualProperties.XAxisMaximumFixedValue;
176
177      foreach (var x in newPlot.Rows.Zip(oldPlot.Rows, (nr, or) => new { nr, or })) {
178        var newVisuapProperties = (ScatterPlotDataRowVisualProperties)x.or.VisualProperties.Clone();
179        newVisuapProperties.DisplayName = x.nr.VisualProperties.DisplayName;
180        x.nr.VisualProperties = newVisuapProperties;
181      }
182    }
183
184    private void comboBoxGroup_SelectedIndexChanged(object sender, EventArgs e) {
185      useGradientCheckBox.Enabled = (string)comboBoxGroup.SelectedItem != NoGroupItem;
186      gradientPanel.Visible = useGradientCheckBox.Enabled && useGradientCheckBox.Checked;
187      UpdateScatterPlot();
188    }
189
190    #region Regression Line
191    private void regressionTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) {
192      var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
193      polynomialRegressionOrderNumericUpDown.Enabled = regressionType == RegressionType.Polynomial;
194
195      UpdateRegressionLine();
196    }
197
198    private void polynomialRegressionOrderNumericUpDown_ValueChanged(object sender, EventArgs e) {
199      UpdateRegressionLine();
200    }
201
202    private void UpdateRegressionLine() {
203      var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
204      int order = (int)polynomialRegressionOrderNumericUpDown.Value;
205
206      var rows = scatterPlotControl.Content.Rows.ToList();
207      scatterPlotControl.Content.Rows.Clear();
208      foreach (var row in rows) {
209        row.VisualProperties.IsRegressionVisibleInLegend = false;
210        row.VisualProperties.RegressionType = regressionType;
211        row.VisualProperties.PolynomialRegressionOrder = order;
212      }
213      scatterPlotControl.Content.Rows.AddRange(rows);
214    }
215    #endregion
216
217    private void useGradientCheckBox_CheckedChanged(object sender, EventArgs e) {
218      gradientPanel.Visible = useGradientCheckBox.Enabled && useGradientCheckBox.Checked;
219
220      // remove rows and re-add them later to avoid firing visual property changd events
221      var rows = scatterPlotControl.Content.Rows.ToDictionary(r => r.Name, r => r);
222      scatterPlotControl.Content.Rows.Clear();
223
224      if (useGradientCheckBox.Checked) {
225        var groupVariable = (string)comboBoxGroup.SelectedItem;
226        if (groupVariable == NoGroupItem) return;
227
228        var groupValues = Content.PreprocessingData.GetValues<double>(Content.PreprocessingData.GetColumnIndex(groupVariable))
229          .Distinct().OrderBy(x => x).ToList();
230        double min = groupValues.First(), max = groupValues.Last();
231        foreach (var group in groupValues) {
232          ScatterPlotDataRow row;
233          if (rows.TryGetValue(group.ToString("R"), out row)) {
234            row.VisualProperties.Color = GetColor(group, min, max);
235            row.VisualProperties.IsVisibleInLegend = false;
236          }
237        }
238        gradientMinimumLabel.Text = min.ToString("G5");
239        gradientMaximumLabel.Text = max.ToString("G5");
240      } else {
241        foreach (var row in rows.Values) {
242          row.VisualProperties.Color = Color.Empty;
243          row.VisualProperties.IsVisibleInLegend = true;
244        }
245      }
246      scatterPlotControl.Content.Rows.AddRange(rows.Values);
247    }
248
249    private static Color GetColor(double value, double min, double max) {
250      if (double.IsNaN(value)) {
251        return Color.DarkGray;
252      }
253      var colors = ColorGradient.Colors;
254      int index = (int)((colors.Count - 1) * (value - min) / (max - min));
255      if (index >= colors.Count) index = colors.Count - 1;
256      if (index < 0) index = 0;
257      return colors[index];
258    }
259
260    private void BatchRowUpdate(Action<ScatterPlotDataRow> rowAction) {
261      var scatterPlot = scatterPlotControl.Content;
262      var rows = scatterPlot.Rows.ToList();
263      // remove rows and re-add them later to avoid firing visual property changd events
264      scatterPlot.Rows.Clear();
265      foreach (var row in rows) {
266        rowAction(row);
267      }
268      scatterPlot.Rows.AddRange(rows);
269    }
270  }
271}
272
Note: See TracBrowser for help on using the repository browser.