Vespucci  1.0.0
plotwidget.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright (C) 2014-2016 Wright State University - All Rights Reserved
3  Daniel P. Foose - Maintainer/Lead Developer
4 
5  This file is part of Vespucci.
6 
7  Vespucci 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  Vespucci 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 Vespucci. If not, see <http://www.gnu.org/licenses/>.
19 *******************************************************************************/
20 #include "plotwidget.h"
21 #include "ui_plotwidget.h"
22 #include "Global/global.h"
23 
24 PlotWidget::PlotWidget(QWidget *parent, QSharedPointer<VespucciWorkspace> ws) :
25  QWidget(parent),
26  ui(new Ui::PlotWidget)
27 {
28  workspace_ = ws;
29  transient_graph_ = 0;
30  ui->setupUi(this);
31  ui->customPlot->setInteraction(QCP::iRangeDrag);
32  ui->customPlot->setInteraction(QCP::iRangeZoom);
33  ui->customPlot->setInteraction(QCP::iSelectItems);
34  ui->customPlot->setInteraction(QCP::iMultiSelect);
35  ui->customPlot->setInteraction(QCP::iSelectLegend);
36  ui->customPlot->setInteraction(QCP::iSelectOther);
37  ui->customPlot->setInteraction(QCP::iSelectPlottables);
38 
39  colors_ = {QColor(228,26,28),
40  QColor(55,126,184),
41  QColor(77,175,74),
42  QColor(152,78,163),
43  QColor(255,127,0),
44  QColor(166,86,40),
45  QColor(247,129,191),
46  QColor(153,153,153)};
47 }
48 
50 {
51  delete ui;
52 }
53 
54 void PlotWidget::AddPlot(const mat & paired_data)
55 {
56  QColor pen_color = this->GetNextColor();
57  QPen pen(pen_color);
58  if (paired_data.n_cols < 2)
59  return;
60  qvec abscissa =
61  qvec::fromStdVector(conv_to<stdvec>::from(paired_data.col(0)));
62  qvec data =
63  qvec::fromStdVector(conv_to<stdvec>::from(paired_data.col(1)));
64  int graph_count = ui->customPlot->graphCount();
65  if (graph_count < 1){
66  ui->customPlot->addGraph();
67  ui->customPlot->graph(graph_count)->addData(abscissa, data);
68  }
69  else{
70  ui->customPlot->addGraph(ui->customPlot->graph(0)->keyAxis(), ui->customPlot->graph(0)->valueAxis());
71  ui->customPlot->graph(graph_count)->addData(abscissa, data);
72  }
73  ui->customPlot->graph(graph_count)->setPen(pen);
74  ui->customPlot->rescaleAxes();
75  ui->customPlot->replot(QCustomPlot::rpImmediate);
76 }
77 
78 void PlotWidget::AddPlot(const vec &abscissa, const vec &data)
79 {
80  QColor pen_color = this->GetNextColor();
81  QPen pen(pen_color);
82  qvec abscissa_qvec =
83  qvec::fromStdVector(conv_to<stdvec>::from(abscissa));
84  qvec data_qvec =
85  qvec::fromStdVector(conv_to<stdvec>::from(data));
86  int graph_count = ui->customPlot->graphCount();
87  if (graph_count < 1){
88  ui->customPlot->addGraph();
89  ui->customPlot->graph(graph_count)->addData(abscissa_qvec, data_qvec);
90  }
91  else{
92  ui->customPlot->addGraph(ui->customPlot->graph(0)->keyAxis(), ui->customPlot->graph(0)->valueAxis());
93  ui->customPlot->graph(graph_count)->addData(abscissa_qvec, data_qvec);
94  }
95  ui->customPlot->graph(graph_count)->setPen(pen);
96  ui->customPlot->rescaleAxes();
97  ui->customPlot->replot(QCustomPlot::rpImmediate);
98 }
99 
100 void PlotWidget::AddTransientPlot(const vec &abscissa, const vec &data)
101 {
102  QColor pen_color = this->GetNextColor();
103  QPen pen(pen_color);
104  if (abscissa.n_rows != data.n_rows) return;
105 
106  if (transient_graph_){
107  qvec abscissa_qvec =
108  qvec::fromStdVector(conv_to<vector<double> >::from(abscissa));
109  qvec data_qvec =
110  qvec::fromStdVector(conv_to<vector<double> >::from(data));
111  transient_graph_->setData(abscissa_qvec, data_qvec);
112  }
113  else{
114  QCPAxis *key_axis;
115  QCPAxis *value_axis;
116  if (ui->customPlot->graphCount()){
117  key_axis = ui->customPlot->graph(0)->keyAxis();
118  value_axis = ui->customPlot->graph(0)->valueAxis();
119  }
120  else{
121  key_axis = 0;
122  value_axis = 0;
123  }
124  ui->customPlot->addGraph(key_axis, value_axis);
125  transient_graph_ = ui->customPlot->graph(ui->customPlot->graphCount() - 1);
126  qvec abscissa_qvec =
127  qvec::fromStdVector(conv_to<vector<double> >::from(abscissa));
128  qvec data_qvec =
129  qvec::fromStdVector(conv_to<vector<double> >::from(data));
130  transient_graph_->addData(abscissa_qvec, data_qvec);
131  }
132  transient_graph_->setPen(pen);
133  ui->customPlot->rescaleAxes();
134  ui->customPlot->replot(QCustomPlot::rpImmediate);
135 }
136 
137 void PlotWidget::AddTransientPlot(const mat & paired_data)
138 {
139  QColor pen_color = this->GetNextColor();
140  QPen pen(pen_color);
141 
142  if (paired_data.n_cols != 2) return;
143 
144  QCPAxis *key_axis;
145  QCPAxis *value_axis;
146  if (transient_graph_){
147  qvec abscissa_qvec =
148  qvec::fromStdVector(conv_to<vector<double> >::from(paired_data.col(0)));
149  qvec data_qvec =
150  qvec::fromStdVector(conv_to<vector<double> >::from(paired_data.col(1)));
151  transient_graph_->setData(abscissa_qvec, data_qvec);
152  }
153  else{
154  if (ui->customPlot->graphCount()){
155  key_axis = ui->customPlot->graph(0)->keyAxis();
156  value_axis = ui->customPlot->graph(0)->valueAxis();
157  }
158  else{
159  key_axis = 0;
160  value_axis = 0;
161  }
162  ui->customPlot->addGraph(key_axis, value_axis);
163  transient_graph_ = ui->customPlot->graph(ui->customPlot->graphCount() - 1);
164  qvec abscissa_qvec =
165  qvec::fromStdVector(conv_to<vector<double> >::from(paired_data.col(0)));
166  qvec data_qvec =
167  qvec::fromStdVector(conv_to<vector<double> >::from(paired_data.col(1)));
168  transient_graph_->addData(abscissa_qvec, data_qvec);
169  }
170  transient_graph_->setPen(pen);
171  ui->customPlot->rescaleAxes();
172  ui->customPlot->replot(QCustomPlot::rpImmediate);
173 }
174 
179 void PlotWidget::AddScatterPlot(const mat &paired_data)
180 {
181  QColor pen_color = this->GetNextColor();
182  QPen pen(pen_color);
183  if (paired_data.n_cols < 2)
184  return;
185  qvec abscissa =
186  qvec::fromStdVector(conv_to<stdvec>::from(paired_data.col(0)));
187  qvec data =
188  qvec::fromStdVector(conv_to<stdvec>::from(paired_data.col(1)));
189  int graph_count = ui->customPlot->graphCount();
190  if (graph_count < 1){
191  ui->customPlot->addGraph();
192  ui->customPlot->graph(graph_count)->addData(abscissa, data);
193  }
194  else{
195  ui->customPlot->addGraph(ui->customPlot->graph(0)->keyAxis(), ui->customPlot->graph(0)->valueAxis());
196  ui->customPlot->graph(graph_count)->addData(abscissa, data);
197  }
198  ui->customPlot->graph(graph_count)->setPen(pen);
199 
200  QCPScatterStyle style(QCPScatterStyle::ssDisc, pen_color, 4);
201  ui->customPlot->graph(graph_count)->setScatterStyle(style);
202  ui->customPlot->graph(graph_count)->setLineStyle(QCPGraph::lsNone);
203  ui->customPlot->rescaleAxes();
204  ui->customPlot->replot(QCustomPlot::rpImmediate);
205 }
206 
212 void PlotWidget::AddScatterPlot(const vec &abscissa, const vec &data)
213 {
214  QColor pen_color = this->GetNextColor();
215  qvec abscissa_qvec =
216  qvec::fromStdVector(conv_to<stdvec>::from(abscissa));
217  qvec data_qvec =
218  qvec::fromStdVector(conv_to<stdvec>::from(data));
219  int graph_count = ui->customPlot->graphCount();
220  if (graph_count < 1){
221  ui->customPlot->addGraph();
222  ui->customPlot->graph(graph_count)->addData(abscissa_qvec, data_qvec);
223  }
224  else{
225  ui->customPlot->addGraph(ui->customPlot->graph(0)->keyAxis(), ui->customPlot->graph(0)->valueAxis());
226  ui->customPlot->graph(graph_count)->addData(abscissa_qvec, data_qvec);
227  }
228 
229  QCPScatterStyle style(QCPScatterStyle::ssDisc, pen_color, 4);
230  ui->customPlot->graph(graph_count)->setScatterStyle(style);
231  ui->customPlot->graph(graph_count)->setLineStyle(QCPGraph::lsNone);
232  ui->customPlot->rescaleAxes();
233  ui->customPlot->replot(QCustomPlot::rpImmediate);
234 }
235 
241 void PlotWidget::AddMappedScatterPlot(const mat &paired_data, const vec &categorical)
242 {
243  //ignore incomplete categorical data
244  if (categorical.n_rows != paired_data.n_rows){
245  AddScatterPlot(paired_data);
246  return;
247  }
248 
249  vec unique_values = unique(categorical);
250  int color_index;
251  for (uword i = 0; i < unique_values.n_rows; ++i){
252  color_index = i;
253  while (color_index >= colors_.size()){color_index -= colors_.size();}
254  QColor color = colors_[color_index];
255  QCPScatterStyle style(QCPScatterStyle::ssDisc, color, 4);
256  double value = unique_values(i);
257  uvec indices = arma::find(categorical == value);
258  mat current_data = paired_data.rows(indices);
259  qvec x = qvec::fromStdVector(conv_to<stdvec>::from(current_data.col(0)));
260  qvec y = qvec::fromStdVector(conv_to<stdvec>::from(current_data.col(1)));
261 
262  int graph_count = ui->customPlot->graphCount();
263  if (graph_count < 1){
264  ui->customPlot->addGraph();
265  ui->customPlot->graph(graph_count)->addData(x, y);
266  }
267  else{
268  ui->customPlot->addGraph(ui->customPlot->graph(0)->keyAxis(), ui->customPlot->graph(0)->valueAxis());
269  ui->customPlot->graph(graph_count)->addData(x, y);
270  }
271 
272  ui->customPlot->graph(graph_count)->setScatterStyle(style);
273  ui->customPlot->graph(graph_count)->setLineStyle(QCPGraph::lsNone);
274  }
275  ui->customPlot->rescaleAxes();
276  ui->customPlot->replot(QCustomPlot::rpImmediate);
277 }
278 
285 void PlotWidget::AddMappedScatterPlot(const vec &abscissa, const vec &data, const vec &categorical)
286 {
287  if (data.n_rows != abscissa.n_rows) return;
288  //ignore incomplete categorical data
289  if (categorical.n_rows != data.n_rows){
290  AddScatterPlot(abscissa, data);
291  return;
292  }
293 
294  vec unique_values = unique(categorical);
295  int color_index;
296  for (uword i = 0; i < unique_values.n_rows; ++i){
297  color_index = i;
298  while (color_index >= colors_.size()){color_index -= colors_.size();}
299  QColor color = colors_[color_index];
300  QCPScatterStyle style(QCPScatterStyle::ssDisc, color, 4);
301  double value = unique_values(i);
302  uvec indices = arma::find(categorical == value);
303  vec current_data = data.rows(indices);
304  vec current_abscissa = abscissa.rows(indices);
305  qvec x = qvec::fromStdVector(conv_to<stdvec>::from(current_abscissa));
306  qvec y = qvec::fromStdVector(conv_to<stdvec>::from(current_data));
307 
308  int graph_count = ui->customPlot->graphCount();
309  if (graph_count < 1){
310  ui->customPlot->addGraph();
311  ui->customPlot->graph(graph_count)->addData(x, y);
312  }
313  else{
314  ui->customPlot->addGraph(ui->customPlot->graph(0)->keyAxis(), ui->customPlot->graph(0)->valueAxis());
315  ui->customPlot->graph(graph_count)->addData(x, y);
316  }
317 
318  ui->customPlot->graph(graph_count)->setScatterStyle(style);
319  ui->customPlot->graph(graph_count)->setLineStyle(QCPGraph::lsNone);
320 
321  }
322  ui->customPlot->rescaleAxes();
323  ui->customPlot->replot(QCustomPlot::rpImmediate);
324 }
325 
327 {
328  if (transient_graph_){
329  ui->customPlot->removeGraph(transient_graph_);
330  transient_graph_ = 0;
331  ui->customPlot->rescaleAxes();
332  ui->customPlot->replot(QCustomPlot::rpImmediate);
333  }
334 }
335 
337 {
338  return (transient_graph_ && ui->customPlot->graphCount() == 1);
339 }
340 
341 void PlotWidget::SavePlot(QString filename)
342 {
343  Vespucci::SavePlot(ui->customPlot, filename);
344 }
345 
346 QColor PlotWidget::GetNextColor()
347 {
348  //there are nine colors in the list
349  //we alternate between them then rotate back to the first
350  int color_index = ui->customPlot->graphCount();
351  while (color_index >= colors_.size()){color_index -= colors_.size();}
352  return colors_[color_index];
353 }
void AddScatterPlot(const mat &paired_data)
PlotWidget::AddScatterPlot.
Definition: plotwidget.cpp:179
PlotWidget(QWidget *parent, QSharedPointer< VespucciWorkspace > ws)
Definition: plotwidget.cpp:24
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes) ...
Definition: qcustomplot.h:160
Definition: ahcadialog.h:26
0x080 All other objects are selectable (e.g. your own derived layerables, the plot title...
Definition: qcustomplot.h:167
void SavePlot(QString filename)
Definition: plotwidget.cpp:341
0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) ...
Definition: qcustomplot.h:163
0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see QCPAbstractItem) ...
Definition: qcustomplot.h:166
Manages a single axis inside a QCustomPlot.
Definition: qcustomplot.h:985
Represents the visual appearance of scatter points.
Definition: qcustomplot.h:239
void RemoveTransientPlot()
Definition: plotwidget.cpp:326
QVector< double > qvec
Definition: mapplot.h:28
0x004 The user can select multiple objects by holding the modifier set by QCustomPlot::setMultiSelect...
Definition: qcustomplot.h:162
void AddTransientPlot(const vec &abscissa, const vec &data)
Definition: plotwidget.cpp:100
void setPen(const QPen &pen)
0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) ...
Definition: qcustomplot.h:165
void AddPlot(const mat &paired_data)
Definition: plotwidget.cpp:54
{ssDisc.png} a circle which is filled with the pen&#39;s color (not the brush as with ssCircle) ...
Definition: qcustomplot.h:256
bool TransientOnly() const
Definition: plotwidget.cpp:336
The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot...
Definition: qcustomplot.h:1715
void AddMappedScatterPlot(const mat &paired_data, const vec &categorical)
PlotWidget::AddMappedScatterPlot.
Definition: plotwidget.cpp:241
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom, QCPAxisRect::setRangeZoomAxes)
Definition: qcustomplot.h:161
void setData(QCPDataMap *data, bool copy=false)
void addData(const QCPDataMap &dataMap)
bool SavePlot(QCustomPlot *plot, QString filename)
Vespucci::SavePlot.
Definition: global.cpp:30