Changeset 14852 for trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.cs
- Timestamp:
- 04/11/17 18:43:17 (7 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.cs
r14851 r14852 33 33 34 34 namespace HeuristicLab.Problems.DataAnalysis.Views { 35 [View(" Target Response Gradients")]35 [View("Partial Dependence Plots")] 36 36 [Content(typeof(IRegressionSolution))] 37 public partial class RegressionSolution TargetResponseGradientView : DataAnalysisSolutionEvaluationView {38 private readonly Dictionary<string, I GradientChart> gradientCharts;37 public partial class RegressionSolutionPartialDependencePlotView : DataAnalysisSolutionEvaluationView { 38 private readonly Dictionary<string, IPartialDependencePlot> partialDependencePlots; 39 39 private readonly Dictionary<string, DensityChart> densityCharts; 40 40 private readonly Dictionary<string, Panel> groupingPanels; … … 50 50 } 51 51 } 52 private IEnumerable<I GradientChart> VisibleGradientCharts {53 get { return VisibleVariables.Select(v => gradientCharts[v]); }52 private IEnumerable<IPartialDependencePlot> VisiblePartialDependencePlots { 53 get { return VisibleVariables.Select(v => partialDependencePlots[v]); } 54 54 } 55 55 private IEnumerable<DensityChart> VisibleDensityCharts { … … 60 60 } 61 61 62 public RegressionSolution TargetResponseGradientView() {62 public RegressionSolutionPartialDependencePlotView() { 63 63 InitializeComponent(); 64 gradientCharts = new Dictionary<string, IGradientChart>();64 partialDependencePlots = new Dictionary<string, IPartialDependencePlot>(); 65 65 densityCharts = new Dictionary<string, DensityChart>(); 66 66 groupingPanels = new Dictionary<string, Panel>(); … … 137 137 138 138 // create controls 139 gradientCharts.Clear();139 partialDependencePlots.Clear(); 140 140 densityCharts.Clear(); 141 141 groupingPanels.Clear(); 142 142 foreach (var variableName in doubleVariables) { 143 var gradientChart = CreateGradientChart(variableName, sharedFixedVariables);144 gradientCharts.Add(variableName, gradientChart);143 var plot = CreatePartialDependencePlot(variableName, sharedFixedVariables); 144 partialDependencePlots.Add(variableName, plot); 145 145 146 146 var densityChart = new DensityChart() { … … 149 149 Height = 12, 150 150 Visible = false, 151 Top = (int)( gradientChart.Height * 0.1),151 Top = (int)(plot.Height * 0.1), 152 152 }; 153 153 densityCharts.Add(variableName, densityChart); 154 154 155 gradientChart.ZoomChanged += (o, e) => {156 var gradient = (GradientChart)o;157 var density = densityCharts[ gradient.FreeVariable];158 density.Visible = densityComboBox.SelectedIndex != 0 && ! gradient.IsZoomed;155 plot.ZoomChanged += (o, e) => { 156 var pdp = (PartialDependencePlot)o; 157 var density = densityCharts[pdp.FreeVariable]; 158 density.Visible = densityComboBox.SelectedIndex != 0 && !pdp.IsZoomed; 159 159 if (density.Visible) 160 UpdateDensityChart(density, gradient.FreeVariable);161 }; 162 gradientChart.SizeChanged += (o, e) => {163 var gradient = (GradientChart)o;164 var density = densityCharts[ gradient.FreeVariable];165 density.Top = (int)( gradient.Height * 0.1);160 UpdateDensityChart(density, pdp.FreeVariable); 161 }; 162 plot.SizeChanged += (o, e) => { 163 var pdp = (PartialDependencePlot)o; 164 var density = densityCharts[pdp.FreeVariable]; 165 density.Top = (int)(pdp.Height * 0.1); 166 166 }; 167 167 168 168 // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...) 169 169 // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting. 170 gradientChart.ChartPostPaint += OnGradientChartPostPaint;170 plot.ChartPostPaint += OnPartialDependencePlotPostPaint; 171 171 172 172 var panel = new Panel() { … … 177 177 178 178 panel.Controls.Add(densityChart); 179 panel.Controls.Add( gradientChart);179 panel.Controls.Add(plot); 180 180 groupingPanels.Add(variableName, panel); 181 181 } 182 182 foreach (var variableName in factorVariables) { 183 var gradientChart = CreateFactorGradientChart(variableName, sharedFixedVariables);184 gradientCharts.Add(variableName, gradientChart);183 var plot = CreateFactorPartialDependencePlot(variableName, sharedFixedVariables); 184 partialDependencePlots.Add(variableName, plot); 185 185 186 186 var densityChart = new DensityChart() { … … 189 189 Height = 12, 190 190 Visible = false, 191 Top = (int)( gradientChart.Height * 0.1),191 Top = (int)(plot.Height * 0.1), 192 192 }; 193 193 densityCharts.Add(variableName, densityChart); 194 gradientChart.ZoomChanged += (o, e) => {195 var gradient = (FactorGradientChart)o;196 var density = densityCharts[ gradient.FreeVariable];197 density.Visible = densityComboBox.SelectedIndex != 0 && ! gradient.IsZoomed;194 plot.ZoomChanged += (o, e) => { 195 var pdp = (FactorPartialDependencePlot)o; 196 var density = densityCharts[pdp.FreeVariable]; 197 density.Visible = densityComboBox.SelectedIndex != 0 && !pdp.IsZoomed; 198 198 if (density.Visible) 199 UpdateDensityChart(density, gradient.FreeVariable);200 }; 201 gradientChart.SizeChanged += (o, e) => {202 var gradient = (FactorGradientChart)o;203 var density = densityCharts[ gradient.FreeVariable];204 density.Top = (int)( gradient.Height * 0.1);199 UpdateDensityChart(density, pdp.FreeVariable); 200 }; 201 plot.SizeChanged += (o, e) => { 202 var pdp = (FactorPartialDependencePlot)o; 203 var density = densityCharts[pdp.FreeVariable]; 204 density.Top = (int)(pdp.Height * 0.1); 205 205 }; 206 206 207 207 // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...) 208 208 // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting. 209 gradientChart.ChartPostPaint += OnFactorGradientChartPostPaint;209 plot.ChartPostPaint += OnFactorPartialDependencePlotPostPaint; 210 210 211 211 var panel = new Panel() { … … 216 216 217 217 panel.Controls.Add(densityChart); 218 panel.Controls.Add( gradientChart);218 panel.Controls.Add(plot); 219 219 groupingPanels.Add(variableName, panel); 220 220 } … … 237 237 double yValue = Content.Model.GetEstimatedValues(sharedFixedVariables, new[] { 0 }).Single(); 238 238 string title = Content.ProblemData.TargetVariable + ": " + yValue.ToString("G5", CultureInfo.CurrentCulture); 239 foreach (var chart in gradientCharts.Values) {239 foreach (var chart in partialDependencePlots.Values) { 240 240 if (!string.IsNullOrEmpty(chart.YAxisTitle)) { // only show title for first column in grid 241 241 chart.YAxisTitle = title; … … 245 245 246 246 247 private void On GradientChartPostPaint(object o, EventArgs e) {248 var gradient = (GradientChart)o;249 var density = densityCharts[ gradient.FreeVariable];250 251 density.Width = gradient.Width;252 253 var gcPlotPosition = gradient.InnerPlotPosition;254 density.Left = (int)(gcPlotPosition.X / 100.0 * gradient.Width);255 density.Width = (int)(gcPlotPosition.Width / 100.0 * gradient.Width);256 gradient.UpdateTitlePosition();247 private void OnPartialDependencePlotPostPaint(object o, EventArgs e) { 248 var plot = (PartialDependencePlot)o; 249 var density = densityCharts[plot.FreeVariable]; 250 251 density.Width = plot.Width; 252 253 var gcPlotPosition = plot.InnerPlotPosition; 254 density.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width); 255 density.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width); 256 plot.UpdateTitlePosition(); 257 257 258 258 // removed after succesful layouting due to performance reasons 259 259 if (gcPlotPosition.Width != 0) 260 gradient.ChartPostPaint -= OnGradientChartPostPaint;261 } 262 263 private void OnFactor GradientChartPostPaint(object o, EventArgs e) {264 var gradient = (FactorGradientChart)o;265 var density = densityCharts[ gradient.FreeVariable];266 267 density.Width = gradient.Width;268 269 var gcPlotPosition = gradient.InnerPlotPosition;270 density.Left = (int)(gcPlotPosition.X / 100.0 * gradient.Width);271 density.Width = (int)(gcPlotPosition.Width / 100.0 * gradient.Width);272 gradient.UpdateTitlePosition();260 plot.ChartPostPaint -= OnPartialDependencePlotPostPaint; 261 } 262 263 private void OnFactorPartialDependencePlotPostPaint(object o, EventArgs e) { 264 var plot = (FactorPartialDependencePlot)o; 265 var density = densityCharts[plot.FreeVariable]; 266 267 density.Width = plot.Width; 268 269 var gcPlotPosition = plot.InnerPlotPosition; 270 density.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width); 271 density.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width); 272 plot.UpdateTitlePosition(); 273 273 274 274 // removed after succesful layouting due to performance reasons 275 275 if (gcPlotPosition.Width != 0) 276 gradient.ChartPostPaint -= OnFactorGradientChartPostPaint;276 plot.ChartPostPaint -= OnFactorPartialDependencePlotPostPaint; 277 277 } 278 278 279 279 private async void RecalculateAndRelayoutCharts() { 280 280 foreach (var variable in VisibleVariables) { 281 var gradientChart = gradientCharts[variable];282 await gradientChart.RecalculateAsync(false, false);283 } 284 gradientChartTableLayout.SuspendLayout();281 var plot = partialDependencePlots[variable]; 282 await plot.RecalculateAsync(false, false); 283 } 284 partialDependencePlotTableLayout.SuspendLayout(); 285 285 SetupYAxis(); 286 286 ReOrderControls(); 287 287 SetStyles(); 288 gradientChartTableLayout.ResumeLayout();289 gradientChartTableLayout.Refresh();288 partialDependencePlotTableLayout.ResumeLayout(); 289 partialDependencePlotTableLayout.Refresh(); 290 290 foreach (var variable in VisibleVariables) { 291 291 DensityChart densityChart; … … 295 295 } 296 296 } 297 private GradientChart CreateGradientChart(string variableName, ModifiableDataset sharedFixedVariables) {298 var gradientChart = new GradientChart {297 private PartialDependencePlot CreatePartialDependencePlot(string variableName, ModifiableDataset sharedFixedVariables) { 298 var plot = new PartialDependencePlot { 299 299 Dock = DockStyle.Fill, 300 300 Margin = Padding.Empty, … … 304 304 YAxisTicks = 5, 305 305 }; 306 gradientChart.VariableValueChanged += async (o, e) => {307 var recalculations = Visible GradientCharts308 .Except(new[] { (I GradientChart)o })306 plot.VariableValueChanged += async (o, e) => { 307 var recalculations = VisiblePartialDependencePlots 308 .Except(new[] { (IPartialDependencePlot)o }) 309 309 .Select(async chart => { 310 310 await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false); … … 315 315 SetupYAxis(); 316 316 }; 317 gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, Points);318 gradientChart.SolutionAdded += gradientChart_SolutionAdded;319 gradientChart.SolutionRemoved += gradientChart_SolutionRemoved;320 return gradientChart;321 } 322 private Factor GradientChart CreateFactorGradientChart(string variableName, ModifiableDataset sharedFixedVariables) {323 var gradientChart = new FactorGradientChart {317 plot.Configure(new[] { Content }, sharedFixedVariables, variableName, Points); 318 plot.SolutionAdded += partialDependencePlot_SolutionAdded; 319 plot.SolutionRemoved += partialDependencePlot_SolutionRemoved; 320 return plot; 321 } 322 private FactorPartialDependencePlot CreateFactorPartialDependencePlot(string variableName, ModifiableDataset sharedFixedVariables) { 323 var plot = new FactorPartialDependencePlot { 324 324 Dock = DockStyle.Fill, 325 325 Margin = Padding.Empty, … … 328 328 YAxisTicks = 5, 329 329 }; 330 gradientChart.VariableValueChanged += async (o, e) => {331 var recalculations = Visible GradientCharts332 .Except(new[] { (Factor GradientChart)o })330 plot.VariableValueChanged += async (o, e) => { 331 var recalculations = VisiblePartialDependencePlots 332 .Except(new[] { (FactorPartialDependencePlot)o }) 333 333 .Select(async chart => { 334 334 await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false); … … 340 340 }; 341 341 var variableValues = Content.ProblemData.Dataset.GetStringValues(variableName).Distinct().OrderBy(n => n).ToList(); 342 gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, variableValues);343 gradientChart.SolutionAdded += gradientChart_SolutionAdded;344 gradientChart.SolutionRemoved += gradientChart_SolutionRemoved;345 return gradientChart;342 plot.Configure(new[] { Content }, sharedFixedVariables, variableName, variableValues); 343 plot.SolutionAdded += partialDependencePlot_SolutionAdded; 344 plot.SolutionRemoved += partialDependencePlot_SolutionRemoved; 345 return plot; 346 346 } 347 347 private void SetupYAxis() { … … 349 349 if (automaticYAxisCheckBox.Checked) { 350 350 double min = double.MaxValue, max = double.MinValue; 351 foreach (var chart in Visible GradientCharts) {351 foreach (var chart in VisiblePartialDependencePlots) { 352 352 if (chart.YMin < min) min = chart.YMin; 353 353 if (chart.YMax > max) max = chart.YMax; … … 361 361 } 362 362 363 foreach (var chart in Visible GradientCharts) {363 foreach (var chart in VisiblePartialDependencePlots) { 364 364 chart.FixedYAxisMin = axisMin; 365 365 chart.FixedYAxisMax = axisMax; … … 370 370 // the table layout containing the controls should be suspended before calling this method 371 371 private void ReOrderControls() { 372 var tl = gradientChartTableLayout;372 var tl = partialDependencePlotTableLayout; 373 373 tl.Controls.Clear(); 374 374 int row = 0, column = 0; … … 380 380 tl.Controls.Add(chartsPanel, column, row); 381 381 382 var chart = gradientCharts[v];382 var chart = partialDependencePlots[v]; 383 383 chart.YAxisTitle = column == 0 ? title : string.Empty; 384 384 column++; … … 392 392 393 393 private void SetStyles() { 394 var tl = gradientChartTableLayout;394 var tl = partialDependencePlotTableLayout; 395 395 tl.RowStyles.Clear(); 396 396 tl.ColumnStyles.Clear(); … … 412 412 } 413 413 414 private async void gradientChart_SolutionAdded(object sender, EventArgs<IRegressionSolution> e) {414 private async void partialDependencePlot_SolutionAdded(object sender, EventArgs<IRegressionSolution> e) { 415 415 var solution = e.Value; 416 foreach (var chart in gradientCharts.Values) {416 foreach (var chart in partialDependencePlots.Values) { 417 417 if (sender == chart) continue; 418 418 await chart.AddSolutionAsync(solution); … … 420 420 } 421 421 422 private async void gradientChart_SolutionRemoved(object sender, EventArgs<IRegressionSolution> e) {422 private async void partialDependencePlot_SolutionRemoved(object sender, EventArgs<IRegressionSolution> e) { 423 423 var solution = e.Value; 424 foreach (var chart in gradientCharts.Values) {424 foreach (var chart in partialDependencePlots.Values) { 425 425 if (sender == chart) continue; 426 426 await chart.RemoveSolutionAsync(solution); … … 431 431 var item = e.Item; 432 432 var variable = item.Text; 433 var gradientChart = gradientCharts[variable];433 var plot = partialDependencePlots[variable]; 434 434 var chartsPanel = groupingPanels[variable]; 435 var tl = gradientChartTableLayout;435 var tl = partialDependencePlotTableLayout; 436 436 437 437 tl.SuspendLayout(); 438 438 if (item.Checked) { 439 439 tl.Controls.Add(chartsPanel); 440 await gradientChart.RecalculateAsync(false, false);440 await plot.RecalculateAsync(false, false); 441 441 } else { 442 442 tl.Controls.Remove(chartsPanel); … … 456 456 limitView.ReadOnly = automaticYAxisCheckBox.Checked; 457 457 SetupYAxis(); 458 gradientChartTableLayout.Refresh();458 partialDependencePlotTableLayout.Refresh(); 459 459 densityComboBox_SelectedIndexChanged(this, EventArgs.Empty); // necessary to realign the density plots 460 460 } … … 464 464 return; 465 465 SetupYAxis(); 466 gradientChartTableLayout.Refresh();466 partialDependencePlotTableLayout.Refresh(); 467 467 densityComboBox_SelectedIndexChanged(this, EventArgs.Empty); // necessary to realign the density plots 468 468 } … … 482 482 var variableName = entry.Key; 483 483 var densityChart = entry.Value; 484 if (!VisibleVariables.Contains(variableName) || gradientCharts[variableName].IsZoomed)484 if (!VisibleVariables.Contains(variableName) || partialDependencePlots[variableName].IsZoomed) 485 485 continue; 486 486 … … 504 504 if (Content.ProblemData.Dataset.VariableHasType<double>(variable)) { 505 505 var data = Content.ProblemData.Dataset.GetDoubleValues(variable, indices).ToList(); 506 var gradientChart = gradientCharts[variable] as GradientChart;507 if ( gradientChart != null) {508 var min = gradientChart.FixedXAxisMin;509 var max = gradientChart.FixedXAxisMax;510 var buckets = gradientChart.DrawingSteps;506 var plot = partialDependencePlots[variable] as PartialDependencePlot; 507 if (plot != null) { 508 var min = plot.FixedXAxisMin; 509 var max = plot.FixedXAxisMax; 510 var buckets = plot.DrawingSteps; 511 511 if (min.HasValue && max.HasValue) { 512 512 densityChart.UpdateChart(data, min.Value, max.Value, buckets); 513 densityChart.Width = gradientChart.Width;514 515 var gcPlotPosition = gradientChart.InnerPlotPosition;516 densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);517 densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);513 densityChart.Width = plot.Width; 514 515 var gcPlotPosition = plot.InnerPlotPosition; 516 densityChart.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width); 517 densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width); 518 518 519 519 densityChart.Visible = true; 520 520 } 521 gradientChart.UpdateTitlePosition();521 plot.UpdateTitlePosition(); 522 522 } 523 523 } else if (Content.ProblemData.Dataset.VariableHasType<string>(variable)) { 524 524 var data = Content.ProblemData.Dataset.GetStringValues(variable).ToList(); 525 var gradientChart = gradientCharts[variable] as FactorGradientChart;526 if ( gradientChart != null) {525 var plot = partialDependencePlots[variable] as FactorPartialDependencePlot; 526 if (plot != null) { 527 527 densityChart.UpdateChart(data); 528 densityChart.Width = gradientChart.Width;529 530 var gcPlotPosition = gradientChart.InnerPlotPosition;531 densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);532 densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);528 densityChart.Width = plot.Width; 529 530 var gcPlotPosition = plot.InnerPlotPosition; 531 densityChart.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width); 532 densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width); 533 533 534 534 densityChart.Visible = true; 535 535 536 gradientChart.UpdateTitlePosition();536 plot.UpdateTitlePosition(); 537 537 } 538 538 } … … 543 543 int columns = Math.Min(VisibleVariables.Count(), MaxColumns); 544 544 if (columns > 0) { 545 var tl = gradientChartTableLayout;545 var tl = partialDependencePlotTableLayout; 546 546 MaxColumns = columns; 547 547 tl.SuspendLayout(); … … 556 556 private async void solution_ModelChanged(object sender, EventArgs e) { 557 557 foreach (var variable in VisibleVariables) { 558 var gradientChart = gradientCharts[variable];558 var pdp = partialDependencePlots[variable]; 559 559 var densityChart = densityCharts[variable]; 560 560 // recalculate and refresh 561 await gradientChart.RecalculateAsync(false, false);562 gradientChart.Refresh();561 await pdp.RecalculateAsync(false, false); 562 pdp.Refresh(); 563 563 UpdateDensityChart(densityChart, variable); 564 564 }
Note: See TracChangeset
for help on using the changeset viewer.