SedSat3 1.1.6
Sediment Source Apportionment Tool - Advanced statistical methods for environmental pollution research
Loading...
Searching...
No Matches
generalchart.cpp
Go to the documentation of this file.
1#include "generalchart.h"
2#include "ui_generalchart.h"
3#include "resultitem.h"
4#include <string>
5
6
7GeneralChart::GeneralChart(QWidget *parent) :
8 QDialog(parent),
9 ui(new Ui::GeneralChart)
10{
11 ui->setupUi(this);
12 chart = new Chart();
14 ui->verticalLayout->addWidget(chartView);
15 connect(ui->Exporttppng,SIGNAL(clicked()),this,SLOT(on_Exporttopng()));
16
17}
18
20{
21 delete ui;
22}
23
25{
26 result_item = res;
27 if (res->Type() == result_type::contribution)
28 {
29
30 Contribution* contributions = static_cast<Contribution*>(res->Result());
31 return PlotContribution(contributions, QString::fromStdString(res->Name()));
32
33 }
35 {
36
37 Elemental_Profile_Set* profile_sets = static_cast<Elemental_Profile_Set*>(res->Result());
38 return PlotProfileSet(profile_sets,QString::fromStdString(res->Name()));
39
40 }
41
43 {
44
45 Elemental_Profile* profile_set = static_cast<Elemental_Profile*>(res->Result());
46 return PlotPredictedConcentration(profile_set,QString::fromStdString(res->Name()));
47
48 }
49
50 if (res->Type() == result_type::vector)
51 {
52 CMBVector* profile = static_cast<CMBVector*>(res->Result());
53 return PlotVector(profile, QString::fromStdString(res->Name()));
54 }
55 if (res->Type() == result_type::vectorset)
56 {
57 CMBVectorSet* profile = static_cast<CMBVectorSet*>(res->Result());
58 return PlotVectorSet(profile, QString::fromStdString(res->Name()));
59 }
60 if (res->Type() == result_type::matrix)
61 {
62 CMBMatrix* matrix = static_cast<CMBMatrix*>(res->Result());
63 return PlotMatrix(matrix, QString::fromStdString(res->Name()));
64 }
65
66
67 if (res->Type() == result_type::mlrset)
68 {
70 return PlotRegressionSet(mlrset, QString::fromStdString(res->Name()));
71 }
73 {
74 CMBTimeSeriesSet* timeseriesset = static_cast<CMBTimeSeriesSet*>(res->Result());
75 return PlotTimeSeriesSet(timeseriesset, QString::fromStdString(res->Name()),QString::fromStdString(res->XAxisTitle()),QString::fromStdString(res->YAxisTitle()));
76 }
78 {
79 RangeSet* rangeset = static_cast<RangeSet*>(res->Result());
80 return PlotRangeSet(rangeset, QString::fromStdString(res->Name()),QString::fromStdString(res->XAxisTitle()),QString::fromStdString(res->YAxisTitle()));
81 }
82
84 {
85 CMBTimeSeriesSet* timeseriesset = static_cast<CMBTimeSeriesSet*>(res->Result());
86 return PlotTimeSeriesSet_M(timeseriesset, QString::fromStdString(res->Name()),QString::fromStdString(res->XAxisTitle()),QString::fromStdString(res->YAxisTitle()));
87 }
89 {
90 CMBTimeSeriesSet* timeseriesset = static_cast<CMBTimeSeriesSet*>(res->Result());
91 return PlotTimeSeriesSet_M(timeseriesset, QString::fromStdString(res->Name()),QString::fromStdString(res->XAxisTitle()),QString::fromStdString(res->YAxisTitle()));
92 }
94 {
95 CMBTimeSeriesSet* timeseriesset = static_cast<CMBTimeSeriesSet*>(res->Result());
96 return PlotTimeSeriesSet_Stacked(timeseriesset, QString::fromStdString(res->Name()),QString::fromStdString(res->XAxisTitle()),QString::fromStdString(res->YAxisTitle()));
97 }
98
99 if (res->Type() == result_type::mcmc_samples)
100 {
101 CMBTimeSeriesSet* timeseriesset = static_cast<CMBTimeSeriesSet*>(res->Result());
102 return InitializeMCMCSamples(timeseriesset, QString::fromStdString(res->Name()));
103 }
105 {
106 CMBTimeSeriesSet* timeseriesset = static_cast<CMBTimeSeriesSet*>(res->Result());
107 return InitializeDistributions(timeseriesset, QString::fromStdString(res->Name()));
108 }
109 if (res->Type() == result_type::matrix1vs1)
110 {
111 CMBMatrix* matrix = static_cast<CMBMatrix*>(res->Result());
112 return PlotScatter(matrix);
113 }
115 {
116 CMBVectorSet* vector_set = static_cast<CMBVectorSet*>(res->Result());
117 return PlotScatter(vector_set);
118 }
119
121 {
122 CMBVectorSetSet* vector_set = static_cast<CMBVectorSetSet*>(res->Result());
123 return PlotVectorSetSet(vector_set,QString::fromStdString(res->Name()));
124 }
125
126 chartView->update();
127 return false;
128}
129
130double roundDown(double a, double rounding_value) {
131 if (a >= 0)
132 return round(a/rounding_value)*rounding_value;
133 else
134 return -round(-a/rounding_value+1)*rounding_value;
135
136}
137
138bool GeneralChart::PlotVectorSetSet(CMBVectorSetSet *profile, const QString &title)
139{
140 source1_combo = new QComboBox();
141 source2_combo = new QComboBox();
142 QLabel *source1_label = new QLabel();
143 QLabel *source2_label = new QLabel();
144 source1_label->setText("Source group I:");
145 source2_label->setText("Source group II:");
146
147 connect(source1_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onDFAPairChanged(int)));
148 connect(source2_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onDFAPairChanged(int)));
149
150 for (map<std::string,CMBVectorSet>::iterator it = profile->begin(); it!=profile->end(); it++ )
151 {
152 source1_combo->addItem(QString::fromStdString(it->first));
153 source2_combo->addItem(QString::fromStdString(it->first));
154 }
155 ui->horizontalLayout->addWidget(source1_label);
156 ui->horizontalLayout->addWidget(source1_combo);
157 ui->horizontalLayout->addWidget(source2_label);
158 ui->horizontalLayout->addWidget(source2_combo);
159 onDFAPairChanged(source1_combo->currentIndex());
160 return true;
161}
162
163bool GeneralChart::PlotVectorSet(CMBVectorSet *profile, const QString &title)
164{
165 element_combo = new QComboBox();
166 QLabel *element_label = new QLabel();
167 element_label->setText("Source group pair:");
168
169 connect(element_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onPairChanged(int)));
170
171 for (map<std::string,CMBVector>::iterator it = profile->begin(); it!=profile->end(); it++ )
172 {
173 element_combo->addItem(QString::fromStdString(it->first));
174 }
175
176
177 ui->horizontalLayout->addWidget(element_label);
178 ui->horizontalLayout->addWidget(element_combo);
179 onPairChanged(element_combo->currentIndex());
180
181 return true;
182}
183
184bool GeneralChart::PlotVector(CMBVector *profile, const QString &title)
185{
186 QStringList categories;
187
188 QBarCategoryAxis *axisX = new QBarCategoryAxis();
189
190 vector<string> element_names = profile->Labels();
191 for (unsigned int i = 0; i < element_names.size(); i++)
192 categories << QString::fromStdString(element_names[i]);
193
194 axisX->append(categories);
195 chart->addAxis(axisX, Qt::AlignBottom);
196 axisX->setTitleText(QString::fromStdString(result_item->XAxisTitle()));
197 QLogValueAxis* axisYLog = nullptr;
198 QValueAxis* axisYNormal = nullptr;
199 bool _log = (result_item->YAxisMode()==yaxis_mode::log?true:false);
200 double profile_min;
201 if (result_item->AbsValue())
202 profile_min = profile->abs().min();
203 else
204 profile_min = profile->min();
205 if (profile_min>0 && _log)
206 {
207 axisYLog = new QLogValueAxis();
208 if (result_item->AbsValue())
209 axisYLog->setRange(pow(10, roundDown(log(profile->abs().min())/log(10.0))), pow(10, int(log(profile->abs().max()) / log(10.0))+1));
210 else
211 axisYLog->setRange(pow(10, roundDown(log(profile->min())/log(10.0))), pow(10, int(log(profile->max()) / log(10.0))+1));
212 axisYLog->setLabelFormat("%g");
213 axisYLog->setMinorTickCount(5);
214 axisYLog->setTitleText(QString::fromStdString(result_item->YAxisTitle()));
215 chart->addAxis(axisYLog, Qt::AlignLeft);
216 _log = true;
217 }
218 else
219 {
220 axisYNormal = new QValueAxis();
221 if (result_item->AbsValue())
222 axisYNormal->setRange(roundDown(profile->abs().min()*10.0)/10, roundDown((profile->abs().max()+0.1)*10.0)/10);
223 else
224 axisYNormal->setRange(roundDown(profile->min()*10.0)/10, roundDown((profile->max()+0.1)*10.0)/10);
225 axisYNormal->setLabelFormat("%f");
226 axisYNormal->setMinorTickCount(5);
227 axisYNormal->setTitleText(QString::fromStdString(result_item->YAxisTitle()));
228 chart->addAxis(axisYNormal, Qt::AlignLeft);
229 _log = false;
230 }
231 axisX->setLabelsAngle(-90);
232 chart->addAxis(axisX, Qt::AlignBottom);
233
234
235 //QLineSeries* series = new QLineSeries();
236 QBarSeries* series = new QBarSeries();
237
238 chart->addSeries(series);
239 series->setName(title);
240 series->attachAxis(axisX);
241 if (_log)
242 series->attachAxis(axisYLog);
243 else
244 series->attachAxis(axisYNormal);
245
246 double counter = 0.5;
247 QBarSet *barset = new QBarSet(QString::fromStdString(result_item->Name()));
248 QPen pen;
249 pen.setWidth(2);
250 barset->setPen(pen);
251
252 for (int i=0; i<profile->num; i++)
253 {
254 if (result_item->AbsValue())
255 barset->append(fabs(profile->at(i)));
256 else
257 barset->append(profile->at(i));
258 counter++;
259 }
260 series->append(barset);
261 return true;
262
263}
264
265
266bool GeneralChart::PlotMatrix(CMBMatrix *matrix, const QString &title)
267{
268 QStringList categories;
269
270 QBarCategoryAxis *axisX = new QBarCategoryAxis();
271
272 vector<string> element_names = matrix->ColumnLabels();
273 for (unsigned int i = 0; i < element_names.size(); i++)
274 categories << QString::fromStdString(element_names[i]);
275
276 axisX->append(categories);
277 chart->addAxis(axisX, Qt::AlignBottom);
278
279 QLogValueAxis* axisYLog = nullptr;
280 QValueAxis* axisYNormal = nullptr;
281 bool _log = (result_item->YAxisMode()==yaxis_mode::log?true:false);
282 double matrix_min;
283 if (result_item->AbsValue())
284 matrix_min = matrix->abs().min();
285 else
286 matrix_min = matrix->min();
287
288
289 if (matrix_min>0 && _log)
290 {
291 axisYLog = new QLogValueAxis();
292 axisYLog->setRange(pow(10, roundDown(log(matrix_min)/log(10.0))), pow(10, int(log(matrix->max()) / log(10.0))+1));
293 axisYLog->setLabelFormat("%g");
294 axisYLog->setMinorTickCount(5);
295 chart->addAxis(axisYLog, Qt::AlignLeft);
296 _log = true;
297 }
298 else
299 {
300 axisYNormal = new QValueAxis();
301 axisYNormal->setRange(roundDown(matrix_min*10.0)/10, roundDown((matrix->max()+0.1)*10.0)/10);
302 axisYNormal->setLabelFormat("%f");
303 axisYNormal->setMinorTickCount(5);
304 chart->addAxis(axisYNormal, Qt::AlignLeft);
305 _log= false;
306 }
307
308 chart->addAxis(axisX, Qt::AlignBottom);
309
310
311 for (int i=0; i<matrix->getnumrows(); i++)
312 { QBarSeries* series = new QBarSeries();
313
314 chart->addSeries(series);
315 series->setName(QString::fromStdString(matrix->RowLabel(i)));
316 series->attachAxis(axisX);
317 if (_log)
318 series->attachAxis(axisYLog);
319 else
320 series->attachAxis(axisYNormal);
321
322 double counter = 0.5;
323 QBarSet *barset = new QBarSet(QString::fromStdString(matrix->RowLabel(i)));
324 QPen pen;
325 pen.setWidth(2);
326 barset->setPen(pen);
327
328 for (int j=0; j<matrix->getnumcols(); j++)
329 {
330 if (result_item->AbsValue())
331 barset->append(fabs(matrix->matr[i][j]));
332 else
333 barset->append(matrix->matr[i][j]);
334 counter++;
335 }
336 series->append(barset);
337 }
338 return true;
339
340
341}
342
343
344bool GeneralChart::PlotProfileSet(Elemental_Profile_Set *profile_sets, const QString &title)
345{
346 QCategoryAxis* axisX = new QCategoryAxis();
347
348 axisX->setRange(0, profile_sets->GetElementNames().size());
349 vector<string> element_names = profile_sets->GetElementNames();
350 for (int i=0; i<element_names.size(); i++)
351 axisX->append(QString::fromStdString(element_names[i]),double(i+1));
352
353
354 QLogValueAxis* axisYLog = nullptr;
355 QValueAxis* axisYNormal = nullptr;
356 bool _log = (result_item->YAxisMode()==yaxis_mode::log?true:false);
357 if (profile_sets->GetMinimum()>0 && _log)
358 {
359 axisYLog = new QLogValueAxis();
360 axisYLog->setRange(pow(10, roundDown(log(profile_sets->GetMinimum())/log(10.0))), pow(10, int(log(profile_sets->GetMaximum()) / log(10.0))+1));
361 axisYLog->setLabelFormat("%g");
362 axisYLog->setMinorTickCount(5);
363 chart->addAxis(axisYLog, Qt::AlignLeft);
364 _log = true;
365 }
366 else
367 {
368 axisYNormal = new QValueAxis();
370 axisYNormal->setRange(roundDown(profile_sets->GetMinimum()), roundDown(profile_sets->GetMaximum()+1));
371 else
372 axisYNormal->setRange(roundDown(profile_sets->GetMinimum()), result_item->YLimit(_range::high));
373 axisYNormal->setLabelFormat("%g");
374 axisYNormal->setMinorTickCount(5);
375 chart->addAxis(axisYNormal, Qt::AlignLeft);
376 // A linear axis was built, so the series must attach to it. PlotVector
377 // already does this; without it, data whose minimum is not positive
378 // takes the log branch below and attaches to an axis never created.
379 _log = false;
380 }
381
382 chart->addAxis(axisX, Qt::AlignBottom);
383
384
385 for (map<string,Elemental_Profile>::iterator it = profile_sets->begin(); it!=profile_sets->end(); it++)
386 {
387 QScatterSeries* series = new QScatterSeries();
388 chart->addSeries(series);
389 series->setName(QString::fromStdString(it->first));
390 series->attachAxis(axisX);
391 if (_log)
392 series->attachAxis(axisYLog);
393 else
394 series->attachAxis(axisYNormal);
395 series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
396 series->setMarkerSize(15.0);
397 double counter=0.5;
398 for (map<string, double>::iterator datapoint = it->second.begin(); datapoint != it->second.end(); datapoint++)
399 {
400 series->append(counter,datapoint->second);
401 counter++;
402 }
403
404 }
405 return true;
406
407}
408bool GeneralChart::PlotContribution(Contribution* contributions, const QString &title)
409{
410 QPieSeries* series = new QPieSeries();
411 QStringList labels;
412 for (map<string, double>::iterator it = contributions->begin(); it != contributions->end(); it++)
413 {
414 series->append(QString::fromStdString(it->first), it->second * 100);
415 labels.append(QString::number(it->second*100)+"%");
416 }
417
418 chart->addSeries(series);
419 for(auto slice : series->slices())
420 { slice->setLabel(QString("%1%").arg(100*slice->percentage(), 0, 'f', 1));
421 slice->setLabelVisible();
422
423 }
424
425 int i=0;
426 for (map<string, double>::iterator it = contributions->begin(); it != contributions->end(); it++)
427 {
428 chart->legend()->markers(series)[i]->setLabel(QString::fromStdString(it->first));
429 i++;
430 }
431
432 series->setLabelsPosition(QPieSlice::LabelOutside);
433 chart->setTitle(title);
434
435 chartView->setRenderHint(QPainter::Antialiasing);
436 return true;
437}
438bool GeneralChart::PlotPredictedConcentration(Elemental_Profile* profile_set, const QString &title)
439{
440 QCategoryAxis* axisX = new QCategoryAxis();
441 qDebug() << profile_set->GetElementNames().size();
442 axisX->setRange(0, profile_set->size()*10);
443 vector<string> element_names = profile_set->GetElementNames();
444 for (int i = 0; i < element_names.size(); i++)
445 axisX->append(QString::fromStdString(element_names[i]), double(i + 1)*10);
446
447
448 QLogValueAxis* axisYLog = nullptr;
449 QValueAxis* axisYNormal = nullptr;
450 axisX->setTitleText(QString::fromStdString(result_item->XAxisTitle()));
451 bool _log = (result_item->YAxisMode()==yaxis_mode::log?true:false);
452 if (profile_set->GetMinimum()>0 && _log)
453 {
454 axisYLog = new QLogValueAxis();
455 axisYLog->setRange(pow(10, roundDown(log(profile_set->GetMinimum())/log(10.0))), pow(10, int(log(profile_set->GetMaximum()) / log(10.0))+1));
456 axisYLog->setLabelFormat("%g");
457 axisYLog->setMinorTickCount(5);
458 axisYLog->setTitleText(QString::fromStdString(result_item->YAxisTitle()));
459 chart->addAxis(axisYLog, Qt::AlignLeft);
460 _log = true;
461 }
462 else
463 {
464 axisYNormal = new QValueAxis();
466 axisYNormal->setRange(roundDown(profile_set->GetMinimum()), roundDown(profile_set->GetMaximum()+1));
467 else
468 axisYNormal->setRange(roundDown(profile_set->GetMinimum()), result_item->YLimit(_range::low));
469 axisYNormal->setLabelFormat("%f");
470 axisYNormal->setMinorTickCount(5);
471 axisYNormal->setTitleText(QString::fromStdString(result_item->YAxisTitle()));
472 chart->addAxis(axisYNormal, Qt::AlignLeft);
473 // A linear axis was built, so the series must attach to it. PlotVector
474 // already does this; without it, data whose minimum is not positive
475 // takes the log branch below and attaches to an axis never created.
476 _log = false;
477 }
478
479 chart->addAxis(axisX, Qt::AlignBottom);
480
481
482 //QLineSeries* series = new QLineSeries();
483 QScatterSeries* series = new QScatterSeries();
484 chart->addSeries(series);
485 series->setName(title);
486 series->attachAxis(axisX);
487 if (_log)
488 series->attachAxis(axisYLog);
489 else
490 series->attachAxis(axisYNormal);
491 series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
492 series->setMarkerSize(15.0);
493 double counter = 0.5;
494 for (map<string, double>::iterator datapoint = profile_set->begin(); datapoint != profile_set->end(); datapoint++)
495 {
496 series->append(counter*10, datapoint->second);
497 counter++;
498 }
499 return true;
500
501
502}
503bool GeneralChart::PlotRegressionSet(MultipleLinearRegressionSet *regressionset, const QString &title)
504{
505 element_combo = new QComboBox();
506 QLabel *element_label = new QLabel();
507 element_label->setText("Constituent:");
508 independent_combo = new QComboBox();
509
510 connect(element_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onElementChanged(int)));
511 connect(independent_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onIndependentChanged(int)));
512 for (map<std::string,MultipleLinearRegression>::iterator it = regressionset->begin(); it!=regressionset->end(); it++ )
513 {
514 element_combo->addItem(QString::fromStdString(it->first));
515 }
516
517 QLabel *independent_label = new QLabel();
518 independent_label->setText("Independent Variable:");
519 ui->horizontalLayout->addWidget(element_label);
520 ui->horizontalLayout->addWidget(element_combo);
521 ui->horizontalLayout->addWidget(independent_label);
522 ui->horizontalLayout->addWidget(independent_combo);
523 onElementChanged(element_combo->currentIndex());
525 return true;
526}
527
528bool GeneralChart:: InitializeMCMCSamples(CMBTimeSeriesSet *mcmcsamples, const QString &title)
529{
530 element_combo = new QComboBox();
531 QLabel *element_label = new QLabel();
532 element_label->setText("Variable:");
533 ui->horizontalLayout->addWidget(element_label);
534 ui->horizontalLayout->addWidget(element_combo);
535
536 for (int i = 0; i<mcmcsamples->size(); i++ )
537 {
538 element_combo->addItem(QString::fromStdString(mcmcsamples->getSeriesName(i)));
539 }
540 connect(element_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onMCMCVariableChanged(int)));
541
542
543 onMCMCVariableChanged(element_combo->currentIndex());
544
545 return true;
546}
547
548bool GeneralChart::InitializeDistributions(CMBTimeSeriesSet *distributions, const QString &title)
549{
550 element_combo = new QComboBox();
551 QLabel *element_label = new QLabel();
552 element_label->setText("Variable:");
553 ui->horizontalLayout->addWidget(element_label);
554 ui->horizontalLayout->addWidget(element_combo);
555
556 for (int i = 0; i<distributions->size(); i++ )
557 {
558 element_combo->addItem(QString::fromStdString(distributions->getSeriesName(i)));
559 }
560 connect(element_combo, SIGNAL(currentIndexChanged(int)),this, SLOT(onDistributionsVariableChanged(int)));
561
562
564
565 return true;
566}
567
568
570{
572 independent_combo->clear();
573 QString constituent = element_combo->itemText(i_element);
574 for (unsigned int i=0; i<mlrset->at(constituent.toStdString()).GetIndependentVariableNames().size(); i++)
575 {
576 independent_combo->addItem(QString::fromStdString(mlrset->at(constituent.toStdString()).GetIndependentVariableNames()[i]));
577 }
578 if (!independent_combo->currentText().isEmpty() && !element_combo->currentText().isEmpty())
579 {
580 PlotRegression(&mlrset->at(constituent.toStdString()),independent_combo->currentText());
581 }
582
583}
584
586{
587 chart->removeAllSeries();
588 for (int i=0; i<chart->axes().size(); i++)
589 chart->removeAxis(chart->axes()[i]);
590
591 for (int i=0; i<chart->axes(Qt::Vertical).size(); i++)
592 {
593 chart->removeAxis(chart->axes(Qt::Vertical)[i]);
594 }
595
596 for (int i=0; i<chart->axes(Qt::Horizontal).size(); i++)
597 {
598 chart->removeAxis(chart->axes(Qt::Horizontal)[i]);
599 }
601 QString pair = element_combo->itemText(pair_id);
602 PlotVector(&vectorset->at(pair.toStdString()),"DFA S value between '" + pair + "'");
603
604}
605
607{
608 chart->removeAllSeries();
609 for (int i=0; i<chart->axes().size(); i++)
610 chart->removeAxis(chart->axes()[i]);
611
612 for (int i=0; i<chart->axes(Qt::Vertical).size(); i++)
613 {
614 chart->removeAxis(chart->axes(Qt::Vertical)[i]);
615 }
616
617 for (int i=0; i<chart->axes(Qt::Horizontal).size(); i++)
618 {
619 chart->removeAxis(chart->axes(Qt::Horizontal)[i]);
620 }
622 qDebug()<<source1_combo->currentText();
623 qDebug()<<source2_combo->currentText();
624 if (source1_combo->currentText()!="" && source2_combo->currentText()!="")
625 PlotScatter(&vectorset->at(source1_combo->currentText().toStdString()),&vectorset->at(source2_combo->currentText().toStdString()), "WB_" + source1_combo->currentText(), "WB_" + source2_combo->currentText() );
626}
627
629{
630 CMBTimeSeriesSet * samplesset = static_cast<CMBTimeSeriesSet*>(result_item->Result());
631 QString variable = element_combo->itemText(i);
632 PlotMCMCSamples(&samplesset->operator[](variable.toStdString()),variable);
633}
634
636{
637 CMBTimeSeriesSet * samplesset = static_cast<CMBTimeSeriesSet*>(result_item->Result());
638 QString variable = element_combo->itemText(i);
639 if (samplesset->Contains(variable.toStdString()))
640 PlotDistribution(&samplesset->operator[](variable.toStdString()),variable);
641}
643{
645 if (!independent_combo->currentText().isEmpty() && !element_combo->currentText().isEmpty())
646 {
647 PlotRegression(&mlrset->at(element_combo->currentText().toStdString()),independent_combo->currentText());
648 }
649
650}
651
652bool GeneralChart::PlotRegression(MultipleLinearRegression *mlr,const QString& independent_var)
653{
654
655 for (int i=0; i<chart->axes(Qt::Horizontal).size(); i++)
656 {
657 qDebug()<<chart->axes(Qt::Horizontal)[i]->objectName();
658 }
659
660 for (int i=0; i<chart->axes(Qt::Vertical).size(); i++)
661 {
662 qDebug()<<chart->axes(Qt::Vertical)[i]->objectName();
663 }
664
665 chart->removeAllSeries();
666 for (int i=0; i<chart->axes().size(); i++)
667 {
668 chart->removeAxis(chart->axes()[i]);
669 //delete chart->axes()[i];
670 }
671
672 qDebug()<<"After:";
673 for (int i=0; i<chart->axes(Qt::Horizontal).size(); i++)
674 {
675 qDebug()<<chart->axes(Qt::Horizontal)[i]->objectName();
676 chart->removeAxis(chart->axes(Qt::Horizontal)[i]);
677 }
678
679 for (int i=0; i<chart->axes(Qt::Vertical).size(); i++)
680 {
681 qDebug()<<chart->axes(Qt::Vertical)[i]->objectName();
682 chart->removeAxis(chart->axes(Qt::Vertical)[i]);
683 }
684 chart->axes().clear();
685 QValueAxis* axisX = new QValueAxis();
686 QValueAxis* axisYNormal = new QValueAxis();
687 axisX->setObjectName("axisX");
688 axisYNormal->setObjectName("axisY");
689
690 QLineSeries *lineseries = new QLineSeries();
691 double x_min_val = CVector(mlr->IndependentData(independent_var.toStdString())).min();
692 double x_max_val = CVector(mlr->IndependentData(independent_var.toStdString())).max();
693 double y_min_val, y_max_val;
694
695 if (mlr->Equation()==regression_form::linear)
696 { y_min_val = mlr->CoefficientsIntercept()[0];
697 y_max_val = mlr->CoefficientsIntercept()[0];
698 }
699 else
700 {
701 y_min_val = exp(mlr->CoefficientsIntercept()[0]);
702 y_max_val = exp(mlr->CoefficientsIntercept()[0]);
703 }
704 for (int i=0; i<mlr->GetIndependentVariableNames().size(); i++)
705 {
706 if (mlr->GetIndependentVariableNames()[i]!=independent_var.toStdString())
707 {
708 if (mlr->Equation()==regression_form::linear)
709 { y_min_val += mlr->MeanIndependentVar(i)*mlr->CoefficientsIntercept()[i+1];
710 y_max_val += mlr->MeanIndependentVar(i)*mlr->CoefficientsIntercept()[i+1];
711 }
712 else
713 {
714 y_min_val *= exp(log(mlr->GeoMeanIndependentVar(i))*mlr->CoefficientsIntercept()[i+1]);
715 y_max_val *= exp(log(mlr->GeoMeanIndependentVar(i))*mlr->CoefficientsIntercept()[i+1]);
716 }
717 }
718 else
719 {
720 if (mlr->Equation()==regression_form::linear)
721 { y_min_val += x_min_val*mlr->CoefficientsIntercept()[i+1];
722 y_max_val += x_max_val*mlr->CoefficientsIntercept()[i+1];
723 }
724 else
725 {
726 y_min_val *= exp(log(x_min_val)*mlr->CoefficientsIntercept()[i+1]);
727 y_max_val *= exp(log(x_max_val)*mlr->CoefficientsIntercept()[i+1]);
728 }
729 }
730 }
731
732 axisX->setRange(CVector(mlr->IndependentData(independent_var.toStdString())).min(), CVector(mlr->IndependentData(independent_var.toStdString())).max());
733 axisX->setTitleText(independent_var);
734
735 //axisYNormal->setLabelFormat("%f");
736 //axisYNormal->setMinorTickCount(5);
737 axisYNormal->setTitleText(QString::fromStdString("Measured " + mlr->DependentVariableName()));
738
739
740 QScatterSeries* series = new QScatterSeries();
741
742 series->setName(QString::fromStdString(mlr->DependentVariableName()));
743 series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
744 series->setMarkerSize(15.0);
745 qDebug()<<independent_var;
746 for (unsigned int i=0; i<mlr->IndependentData(independent_var.toStdString()).size(); i++)
747 {
748 qDebug()<<mlr->DependentData()[i] << ","<< mlr->IndependentData(independent_var.toStdString())[i];
749 series->append(mlr->IndependentData(independent_var.toStdString())[i],mlr->DependentData()[i]);
750 }
751
752 chart->addAxis(axisX, Qt::AlignBottom);
753 chart->addAxis(axisYNormal, Qt::AlignLeft);
754 chart->addSeries(series);
755 series->attachAxis(axisX);
756 series->attachAxis(axisYNormal);
757
758 if (mlr->Equation()==regression_form::linear)
759 {
760 lineseries->append(x_min_val,y_min_val);
761 lineseries->append(x_max_val,y_max_val);
762 }
763 else
764 {
765 for (double x = x_min_val; x<=x_max_val; x+=(x_max_val-x_min_val)/20.0)
766 {
767 double y = exp(mlr->CoefficientsIntercept()[0]);
768 for (unsigned int i=0; i<mlr->GetIndependentVariableNames().size(); i++)
769 if (mlr->GetIndependentVariableNames()[i]!=independent_var.toStdString())
770 y *= exp(log(mlr->GeoMeanIndependentVar(i))*mlr->CoefficientsIntercept()[i+1]);
771 else
772 y *= exp(log(x)*mlr->CoefficientsIntercept()[i+1]);
773 lineseries->append(x,y);
774 }
775 }
776 chart->addSeries(lineseries);
777 lineseries->attachAxis(axisX);
778 lineseries->attachAxis(axisYNormal);
779 lineseries->setName("Regression");
780 axisYNormal->setRange(std::min(std::min(CVector(mlr->DependentData()).min(),y_min_val),y_max_val),std::max(std::max(CVector(mlr->DependentData()).max(),y_max_val),y_min_val));
781
782 return true;
783}
784
786{
787
788 QValueAxis* axisX = new QValueAxis();
789 QValueAxis* axisYNormal = new QValueAxis();
790 axisX->setObjectName("axisX");
791 axisYNormal->setObjectName("axisY");
792
793 CMBVector vec1 = matrix->GetColumn(matrix->ColumnLabel(0));
794 CMBVector vec2 = matrix->GetColumn(matrix->ColumnLabel(1));
795
796 double x_min_val = matrix->GetColumn(matrix->ColumnLabel(0)).min();
797 double x_max_val = matrix->GetColumn(matrix->ColumnLabel(0)).max();
798 double y_min_val = matrix->GetColumn(matrix->ColumnLabel(1)).min();
799 double y_max_val = matrix->GetColumn(matrix->ColumnLabel(1)).max();
800
801
802 axisX->setRange(x_min_val-(x_max_val-x_min_val)*0.05,x_max_val+(x_max_val-x_min_val)*0.05);
803 axisX->setTitleText(QString::fromStdString(matrix->ColumnLabel(0)));
804 axisYNormal->setRange(y_min_val-(y_max_val-y_min_val)*0.05,y_max_val+(y_max_val-y_min_val)*0.05);
805 axisYNormal->setTitleText(QString::fromStdString(matrix->ColumnLabel(1)));
806
807 chart->addAxis(axisX, Qt::AlignBottom);
808 chart->addAxis(axisYNormal, Qt::AlignLeft);
809
810 QStringList rowcategories = matrix->RowLabelCategories();
811 for (int i=0; i<rowcategories.size();i++)
812 {
813 QScatterSeries* series = new QScatterSeries();
814 qDebug()<<rowcategories[i];
815 for (int j=0; j<matrix->getnumrows(); j++)
816 if (QString::fromStdString(matrix->RowLabel(j))==rowcategories[i])
817 series->append(matrix->matr[j][0],matrix->matr[j][1]);
818
819 QPen pen = series->pen();
820 pen.setWidth(2);
821 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
822 series->setPen(pen);
823
824 series->setName(rowcategories[i]);
825 series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
826 series->setMarkerSize(15.0);
827 chart->addSeries(series);
828 series->attachAxis(axisX);
829 series->attachAxis(axisYNormal);
830
831 }
832
833 return true;
834}
835
837{
838
839 QCategoryAxis* axisX = new QCategoryAxis();
840 QValueAxis* axisYNormal = new QValueAxis();
841 axisX->setObjectName("axisX");
842 axisYNormal->setObjectName("axisY");
843
844 double x_min_val = 0.5;
845 double x_max_val = vectorset->size()+0.5;
846 double y_min_val = vectorset->min();
847 double y_max_val = vectorset->max();
848
849
850 axisX->setRange(x_min_val,x_max_val);
851 axisX->setTitleText(QString::fromStdString(result_item->XAxisTitle()));
852 axisYNormal->setRange(y_min_val-(y_max_val-y_min_val)*0.05,y_max_val+(y_max_val-y_min_val)*0.05);
853 axisYNormal->setTitleText(QString::fromStdString(result_item->YAxisTitle()));
854
855 chart->addAxis(axisX, Qt::AlignBottom);
856 chart->addAxis(axisYNormal, Qt::AlignLeft);
857
858 QStringList categories;
859 int counter = 0;
860 for (map<string, CMBVector>::iterator vec = vectorset->begin(); vec!=vectorset->end(); vec++)
861 {
862 QScatterSeries* series = new QScatterSeries();
863
864 for (int j=0; j<vec->second.num; j++)
865 series->append(counter+1,vec->second[j]);
866
867 counter++;
868 QPen pen = series->pen();
869 pen.setWidth(2);
870 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
871 series->setPen(pen);
872
873 series->setName(QString::fromStdString(vec->first));
874 series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
875 series->setMarkerSize(15.0);
876 chart->addSeries(series);
877 series->attachAxis(axisX);
878 series->attachAxis(axisYNormal);
879 axisX->append(QString::fromStdString(vec->first), counter+0.5);
880 }
881
882 return true;
883}
884
885
886bool GeneralChart::PlotScatter(CMBVectorSet *vectorset1, CMBVectorSet *vectorset2, const QString &xaxisTitle, const QString &yaxisTitle)
887{
888
889 QValueAxis* axisX = new QValueAxis();
890 QValueAxis* axisYNormal = new QValueAxis();
891 axisX->setObjectName("axisX");
892 axisYNormal->setObjectName("axisY");
893
894 double x_min_val = vectorset1->min();
895 double x_max_val = vectorset1->max();
896 double y_min_val = vectorset2->min();
897 double y_max_val = vectorset2->max();
898
899
900 axisX->setRange(x_min_val-(x_max_val-x_min_val)*0.05,x_max_val+(x_max_val-x_min_val)*0.05);
901 axisX->setTitleText(xaxisTitle);
902 axisYNormal->setRange(y_min_val-(y_max_val-y_min_val)*0.05,y_max_val+(y_max_val-y_min_val)*0.05);
903 axisYNormal->setTitleText(yaxisTitle);
904
905 chart->addAxis(axisX, Qt::AlignBottom);
906 chart->addAxis(axisYNormal, Qt::AlignLeft);
907
908 QStringList categories;
909 int counter = 0;
910
911
912 for (map<string, CMBVector>::iterator vec = vectorset1->begin(); vec!=vectorset1->end(); vec++)
913 {
914 QScatterSeries* series = new QScatterSeries();
915
916 TimeSeriesSet<double> vals(2);
917 for (int j=0; j<vec->second.num; j++)
918 {
919 series->append(vec->second[j],vectorset2->at(vec->first)[j]);
920 vals[0].append(j,vec->second[j]);
921 vals[1].append(j,vectorset2->at(vec->first)[j]);
922 }
923
924 double mean1 = vals[0].mean();
925 double mean2 = vals[1].mean();
926 double std1 = vals[0].stddev();
927 double std2 = vals[1].stddev();
928 double Cov = Covariance(vals[0],vals[1]);
929
930 QColor color = QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256));
931 counter++;
932
933
934 series->setName(QString::fromStdString(vec->first));
935 series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
936 series->setMarkerSize(15.0);
937 series->setColor(color);
938 QPen pen = series->pen();
939 pen.setColor(color);
940 pen.setWidth(2);
941 pen.setBrush(color);
942 series->setPen(pen);
943
944 chart->addSeries(series);
945 series->attachAxis(axisX);
946 series->attachAxis(axisYNormal);
947 double rho = Cov/(std1*std2);
948 double major_diagonal;
949 double minor_diagonal;
950 if (std1>=std2)
951 {
952 major_diagonal = 2*sqrt(2*((std1*std1+std2*std2)/2.0 + sqrt(pow((std1*std1-std2*std2)/2.0,2)+pow(rho*std1*std2,2))));
953 minor_diagonal = 2*sqrt(2*((std1*std1+std2*std2)/2.0 - sqrt(pow((std1*std1-std2*std2)/2.0,2)+pow(rho*std1*std2,2))));
954 }
955 else
956 {
957 major_diagonal = 2*sqrt(2*((std1*std1+std2*std2)/2.0 - sqrt(pow((std1*std1-std2*std2)/2.0,2)+pow(rho*std1*std2,2))));
958 minor_diagonal = 2*sqrt(2*((std1*std1+std2*std2)/2.0 + sqrt(pow((std1*std1-std2*std2)/2.0,2)+pow(rho*std1*std2,2))));
959 }
960 double orientation = 0.5*atan(2*rho*std1*std2/(std1*std1-std2*std2));
961
962 qDebug()<<"Std1="<<std1;
963 qDebug()<<"Std2="<<std2;
964 qDebug()<<"Rho="<<rho;
965 qDebug()<<"Major diagonal="<<major_diagonal;
966 qDebug()<<"Minor diagonal="<<minor_diagonal;
967 qDebug()<<"Orienation="<<orientation;
968 vector<QPointF> ellipsepoints = calculateRotatedEllipsePoints(mean1, mean2, major_diagonal, minor_diagonal, orientation, M_PI/30.0);
969 QLineSeries* seriesellipse = new QLineSeries();
970 seriesellipse->setName(QString::fromStdString(vec->first));
971
972 for (size_t i = 0; i<ellipsepoints.size(); i++)
973 {
974 seriesellipse->append(ellipsepoints[i].x(), ellipsepoints[i].y());
975 }
976
977 QPen penellipse = QPen(QBrush(Qt::DashLine),2,Qt::PenStyle::DashLine);
978 penellipse.setColor(color);
979 penellipse.setWidth(2);
980 penellipse.setBrush(color);
981
982 seriesellipse->setPen(penellipse);
983
984 chart->addSeries(seriesellipse);
985
986 for (size_t i = 0; i< chart->legend()->markers(seriesellipse).size(); i++)
987 chart->legend()->markers(seriesellipse)[i]->setVisible(false);
988 seriesellipse->attachAxis(axisX);
989 seriesellipse->attachAxis(axisYNormal);
990
991
992 }
993
994 return true;
995}
996
997
998
999
1000bool GeneralChart::PlotMCMCSamples(TimeSeries<double> *samples,const QString& variable)
1001{
1002
1003 chart->removeAllSeries();
1004 for (int i=0; i<chart->axes().size(); i++)
1005 {
1006 chart->removeAxis(chart->axes()[i]);
1007 //delete chart->axes()[i];
1008 }
1009
1010 for (int i=0; i<chart->axes(Qt::Horizontal).size(); i++)
1011 {
1012 chart->removeAxis(chart->axes(Qt::Horizontal)[i]);
1013 }
1014
1015 for (int i=0; i<chart->axes(Qt::Vertical).size(); i++)
1016 {
1017 chart->removeAxis(chart->axes(Qt::Vertical)[i]);
1018 }
1019 chart->axes().clear();
1020 QValueAxis* axisX = new QValueAxis();
1021 QValueAxis* axisYNormal = new QValueAxis();
1022 axisX->setObjectName("axisX");
1023 axisYNormal->setObjectName("axisY");
1024
1025 double x_min_val = samples->mint();
1026 double x_max_val = samples->maxt();
1027 double y_min_val = samples->minC();
1028 double y_max_val = samples->maxC();
1029
1030
1031 axisX->setRange(x_min_val, x_max_val);
1032 axisX->setTitleText("Sample number");
1033
1034 //axisYNormal->setLabelFormat("%f");
1035 //axisYNormal->setMinorTickCount(5);
1036 axisYNormal->setTitleText(variable);
1037 axisYNormal->setRange(y_min_val, y_max_val);
1038
1039
1040 QScatterSeries* series = new QScatterSeries();
1041
1042 QPen marker_pen(QBrush(Qt::SolidPattern),1,Qt::PenStyle::SolidLine);
1043
1044 series->setName(variable);
1045 series->setMarkerShape(QScatterSeries::MarkerShapeRectangle);
1046 series->setMarkerSize(3.0);
1047 series->setPen(marker_pen);
1048
1049
1050 for (int i=0; i<samples->size(); i++)
1051 {
1052 series->append(samples->getTime(i),samples->getValue(i));
1053 }
1054
1055 chart->addAxis(axisX, Qt::AlignBottom);
1056 chart->addAxis(axisYNormal, Qt::AlignLeft);
1057 chart->addSeries(series);
1058 series->attachAxis(axisX);
1059 series->attachAxis(axisYNormal);
1060
1061 return true;
1062}
1063
1064
1065bool GeneralChart::PlotDistribution(TimeSeries<double> *samples,const QString& variable)
1066{
1067 chart->removeAllSeries();
1068 for (int i=0; i<chart->axes().size(); i++)
1069 {
1070 chart->removeAxis(chart->axes()[i]);
1071 //delete chart->axes()[i];
1072 }
1073
1074 for (int i=0; i<chart->axes(Qt::Horizontal).size(); i++)
1075 {
1076 chart->removeAxis(chart->axes(Qt::Horizontal)[i]);
1077 }
1078
1079 for (int i=0; i<chart->axes(Qt::Vertical).size(); i++)
1080 {
1081 chart->removeAxis(chart->axes(Qt::Vertical)[i]);
1082 }
1083 chart->axes().clear();
1084 QValueAxis* axisX = new QValueAxis();
1085 QValueAxis* axisYNormal = new QValueAxis();
1086 axisX->setObjectName("axisX");
1087 axisYNormal->setObjectName("axisY");
1088
1089 double x_min_val = samples->mint();
1090 double x_max_val = samples->maxt();
1091 double y_min_val = samples->minC();
1092 double y_max_val = samples->maxC();
1093
1094
1095 axisX->setRange(x_min_val, x_max_val);
1096 axisX->setTitleText("Sample number");
1097 axisYNormal->setTitleText(variable);
1098 axisYNormal->setRange(y_min_val, y_max_val);
1099
1100 QLineSeries *series = new QLineSeries();
1101 QAreaSeries *areaseries = new QAreaSeries(series);
1102
1103 QPen marker_pen(QBrush(Qt::SolidPattern),1,Qt::PenStyle::SolidLine);
1104
1105 series->setName(variable);
1106 series->setPen(marker_pen);
1107
1108 for (int i=0; i<samples->size(); i++)
1109 {
1110 series-> append(samples->getTime(i),samples->getValue(i));
1111 }
1112
1113 chart->addAxis(axisX, Qt::AlignBottom);
1114 chart->addAxis(axisYNormal, Qt::AlignLeft);
1115
1116 chart->addSeries(series);
1117 series->attachAxis(axisX);
1118 series->attachAxis(axisYNormal);
1119
1120 chart->addSeries(areaseries);
1121 areaseries->attachAxis(axisX);
1122 areaseries->attachAxis(axisYNormal);
1123
1125 {
1126 QLineSeries *observed_series = new QLineSeries;
1127 QPen observed_pen(QBrush(Qt::DashLine),3,Qt::PenStyle::DashLine);
1128 observed_pen.setColor(Qt::black);
1129 observed_series->setPen(observed_pen);
1130 observed_series->append(static_cast<CMBTimeSeriesSet*>(result_item->Result())->ObservedValue(variable.toStdString()),0);
1131 observed_series->append(static_cast<CMBTimeSeriesSet*>(result_item->Result())->ObservedValue(variable.toStdString()),y_max_val);
1132 chart->addSeries(observed_series);
1133 observed_series->attachAxis(axisX);
1134 observed_series->attachAxis(axisYNormal);
1135 }
1136 return true;
1137}
1138
1139bool GeneralChart::PlotTimeSeriesSet(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title, const QString &y_axis_title)
1140{
1141 double x_min_val = timeseriesset->mintime();
1142 double x_max_val = timeseriesset->maxtime();
1143 double y_min_val = timeseriesset->minval();
1144 double y_max_val = timeseriesset->maxval();
1145 QString xAxisTitle = x_axis_title;
1146 QString yAxisTitle = y_axis_title;
1147 if (x_axis_title.isEmpty()) xAxisTitle = "Value";
1148 if (y_axis_title.isEmpty()) yAxisTitle = "CDF";
1149 QValueAxis* axisX = new QValueAxis();
1150 QValueAxis* axisY = new QValueAxis();
1151 axisX->setObjectName("axisX");
1152 axisY->setObjectName("axisY");
1153 axisX->setTitleText(xAxisTitle);
1154 axisY->setTitleText(yAxisTitle);
1155 axisX->setRange(x_min_val,x_max_val);
1156 axisY->setRange(y_min_val,y_max_val);
1157 chart->addAxis(axisX, Qt::AlignBottom);
1158 chart->addAxis(axisY, Qt::AlignLeft);
1159 for (int i=0; i<timeseriesset->size(); i++)
1160 {
1161 QLineSeries *lineseries = new QLineSeries();
1162 chart->addSeries(lineseries);
1163 lineseries->attachAxis(axisX);
1164 lineseries->attachAxis(axisY);
1165
1166 for (int j=0; j<timeseriesset->at(i).size(); j++)
1167 {
1168 lineseries->append(timeseriesset->at(i).getTime(j),timeseriesset->at(i).getValue(j));
1169 }
1170 QPen pen = lineseries->pen();
1171 pen.setWidth(2);
1172 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
1173 lineseries->setPen(pen);
1174 lineseries->setName(QString::fromStdString(timeseriesset->getSeriesName(i)));
1175
1176 }
1177
1178 return true;
1179}
1180
1181bool GeneralChart::PlotRangeSet(RangeSet *rangeset, const QString &title, const QString &x_axis_title, const QString &y_axis_title)
1182{
1183 double y_min_val = rangeset->minval();
1184 double y_max_val = rangeset->maxval();
1185
1187 {
1188 y_max_val = result_item->YLimit(_range::high);
1189 }
1190
1192 {
1193 y_min_val = result_item->YLimit(_range::low);
1194 }
1195
1197 {
1198 y_min_val = max(y_min_val,1e-8);
1199 }
1200 QString xAxisTitle = x_axis_title;
1201 QString yAxisTitle = y_axis_title;
1202 if (x_axis_title.isEmpty()) xAxisTitle = "Constituent";
1203 if (y_axis_title.isEmpty()) yAxisTitle = "95% CI";
1204 QCategoryAxis* axisX = new QCategoryAxis();
1205
1206 QLogValueAxis* axisYLog = new QLogValueAxis();
1207 QValueAxis* axisY = new QValueAxis();
1208
1209 axisX->setObjectName("axisX");
1210 axisY->setObjectName("axisY");
1211 axisYLog->setObjectName("axisYLog");
1212 axisYLog->setMinorTickCount(10);
1213
1214 axisX->setTitleText(xAxisTitle);
1216 { axisYLog->setTitleText(yAxisTitle);
1217 axisYLog->setRange(y_min_val,y_max_val);
1218 axisYLog->setLabelFormat("%g");
1219 }
1220 else
1221 { axisY->setTitleText(yAxisTitle);
1222 axisY->setRange(y_min_val,y_max_val);
1223 axisYLog->setLabelFormat("%f");
1224 }
1225 axisX->setRange(-0.5,rangeset->size()-0.5);
1226
1227
1228 chart->addAxis(axisX, Qt::AlignBottom);
1230 chart->addAxis(axisYLog, Qt::AlignLeft);
1231 else
1232 chart->addAxis(axisY, Qt::AlignLeft);
1233
1234 double upperlimit = 0.5;
1235 axisX->setStartValue(-0.5);
1236 QBoxPlotSeries *boxWhiskSeries = new QBoxPlotSeries();
1237
1238 for (map<string, Range>::iterator it = rangeset->begin(); it!=rangeset->end(); it++)
1239 {
1240 axisX->append(QString::fromStdString(it->first),upperlimit);
1241 upperlimit += 1;
1242 }
1243
1245 { QScatterSeries* scatterseries = new QScatterSeries();
1246 chart->addSeries(scatterseries);
1247 scatterseries->attachAxis(axisX);
1249 scatterseries->attachAxis(axisYLog);
1250 else
1251 scatterseries->attachAxis(axisY);
1252 int counter = 0;
1253 for (map<string, Range>::iterator it = rangeset->begin(); it!=rangeset->end(); it++)
1254 {
1255 scatterseries->append(counter,it->second.GetValue());
1256 counter++;
1257 }
1258 QPen pen = scatterseries->pen();
1259 pen.setWidth(2);
1260
1261 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
1262 scatterseries->setPen(pen);
1263 scatterseries->setName(QString::fromStdString("Observed value"));
1264 }
1265
1266 for (map<string, Range>::iterator it = rangeset->begin(); it!=rangeset->end(); it++)
1267 {
1268 QBoxSet *boxSet = new QBoxSet();
1269 qDebug()<<it->second.Get(_range::low)<<","<<it->second.Get(_range::high)<<","<<it->second.GetValue();
1270 boxSet->setValue(QBoxSet::LowerExtreme, max(it->second.Get(_range::low),y_min_val));
1271 boxSet->setValue(QBoxSet::UpperExtreme, it->second.Get(_range::high));
1272 boxSet->setValue(QBoxSet::LowerQuartile, max(it->second.Get(_range::low),y_min_val));
1273 boxSet->setValue(QBoxSet::UpperQuartile, it->second.Get(_range::high));
1274 boxSet->setValue(QBoxSet::Median, it->second.Median());
1275 boxWhiskSeries->append(boxSet);
1276
1277
1278 }
1279 QPen brushcolor(QColor(0,200,0,126));
1280 QBrush brush(QColor(0,200,0,126));
1281 boxWhiskSeries->setBrush(brush);
1282 boxWhiskSeries->setName("95% Credible Interval");
1283
1284 chart->addSeries(boxWhiskSeries);
1286 boxWhiskSeries->attachAxis(axisYLog);
1287 else
1288 boxWhiskSeries->attachAxis(axisY);
1289 boxWhiskSeries->attachAxis(axisX);
1290
1291 return true;
1292}
1293
1294bool GeneralChart::PlotTimeSeriesSet_M(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title, const QString &y_axis_title)
1295{
1296 double x_min_val = timeseriesset->mintime();
1297 double x_max_val = timeseriesset->maxtime();
1298 double y_min_val = timeseriesset->minval();
1299 double y_max_val = timeseriesset->maxval();
1300 QValueAxis* axisX = new QValueAxis();
1301 QValueAxis* axisY = new QValueAxis();
1302 QString xAxisTitle = x_axis_title;
1303 QString yAxisTitle = y_axis_title;
1304 if (x_axis_title.isEmpty()) xAxisTitle = "Value";
1305 if (y_axis_title.isEmpty()) yAxisTitle = "CDF";
1306 axisX->setObjectName("axisX");
1307 axisY->setObjectName("axisY");
1308 axisX->setTitleText(xAxisTitle);
1309 axisY->setTitleText(yAxisTitle);
1310 axisX->setRange(x_min_val,x_max_val);
1311 axisY->setRange(y_min_val,y_max_val);
1312 chart->addAxis(axisX, Qt::AlignBottom);
1313 chart->addAxis(axisY, Qt::AlignLeft);
1314 //axisX->setStartValue(x_min_val);
1315 QStringList x_Labels;
1316 int i=0;
1317 {
1318 QScatterSeries* scatterseries = new QScatterSeries();
1319 chart->addSeries(scatterseries);
1320 scatterseries->attachAxis(axisX);
1321 scatterseries->attachAxis(axisY);
1322
1323 for (int j=0; j<timeseriesset->at(i).size(); j++)
1324 {
1325 x_Labels.append(QString::fromStdString(timeseriesset->Label(j)));
1326 //axisX->append(QString::fromStdString(timeseriesset->Label(j)),j+1);
1327 scatterseries->append(timeseriesset->at(i).getTime(j),timeseriesset->at(i).getValue(j));
1328 }
1329 QPen pen = scatterseries->pen();
1330 pen.setWidth(2);
1331
1332 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
1333 scatterseries->setPen(pen);
1334 scatterseries->setName(QString::fromStdString(timeseriesset->getSeriesName(i)));
1335
1336 }
1337 for (int i=1; i<timeseriesset->size(); i++)
1338 {
1339 QLineSeries *lineseries = new QLineSeries();
1340 chart->addSeries(lineseries);
1341 lineseries->attachAxis(axisX);
1342 lineseries->attachAxis(axisY);
1343
1344 for (int j=0; j<timeseriesset->at(i).size(); j++)
1345 {
1346 lineseries->append(timeseriesset->at(i).getTime(j),timeseriesset->at(i).getValue(j));
1347 }
1348 QPen pen = lineseries->pen();
1349 pen.setWidth(2);
1350 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
1351 lineseries->setPen(pen);
1352 lineseries->setName(QString::fromStdString(timeseriesset->getSeriesName(i)));
1353
1354 }
1355
1356 return true;
1357}
1358
1359
1360bool GeneralChart::PlotTimeSeriesSet_A(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title, const QString &y_axis_title)
1361{
1362 double x_min_val = timeseriesset->mintime();
1363 double x_max_val = timeseriesset->maxtime();
1364 double y_min_val = result_item->YLimit(_range::low);
1365 double y_max_val = result_item->YLimit(_range::high);
1366 QCategoryAxis* axisX = new QCategoryAxis();
1367 QValueAxis* axisY = new QValueAxis();
1368 QString xAxisTitle = x_axis_title;
1369 QString yAxisTitle = y_axis_title;
1370 if (x_axis_title.isEmpty()) xAxisTitle = "Value";
1371 if (y_axis_title.isEmpty()) yAxisTitle = "Sample";
1372 axisX->setObjectName("axisX");
1373 axisY->setObjectName("axisY");
1374 axisX->setTitleText(xAxisTitle);
1375 axisY->setTitleText(yAxisTitle);
1376 axisX->setRange(x_min_val,x_max_val);
1377 QStringList XAxisLabels;
1378 axisY->setRange(y_min_val,y_max_val);
1379 chart->addAxis(axisX, Qt::AlignBottom);
1380 chart->addAxis(axisY, Qt::AlignLeft);
1381 for (int i=0; i<timeseriesset->size(); i++)
1382 {
1383 QScatterSeries* scatterseries = new QScatterSeries();
1384 chart->addSeries(scatterseries);
1385 scatterseries->attachAxis(axisX);
1386 scatterseries->attachAxis(axisY);
1387
1388 for (int j=0; j<timeseriesset->at(i).size(); j++)
1389 {
1390 scatterseries->append(timeseriesset->at(i).getTime(j),timeseriesset->at(i).getValue(j));
1391 if (i==0)
1392 axisX->append(QString::fromStdString(timeseriesset->Label(j)),j+0.5);
1393 }
1394
1395 QPen pen = scatterseries->pen();
1396 pen.setWidth(2);
1397
1398 pen.setBrush(QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)));
1399 scatterseries->setPen(pen);
1400 scatterseries->setName(QString::fromStdString(timeseriesset->getSeriesName(i)));
1401
1402 }
1403
1404
1405 return true;
1406}
1407
1408bool GeneralChart::PlotTimeSeriesSet_Stacked(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title, const QString &y_axis_title)
1409{
1410
1411 QVector<QBarSet*> sets(timeseriesset->size());
1412 for (int i=0; i<timeseriesset->size(); i++)
1413 { sets[i] = new QBarSet(QString::fromStdString(timeseriesset->getSeriesName(i)));
1414 for (int j=0; j<timeseriesset->at(i).size(); j++)
1415 *sets[i] << timeseriesset->at(i).getValue(j);
1416
1417 }
1418
1419 QStackedBarSeries *series = new QStackedBarSeries;
1420 for (int i=0; i<timeseriesset->size(); i++)
1421 series->append(sets[i]);
1422
1423 chart->addSeries(series);
1424 chart->setTitle(title);
1425 chart->setAnimationOptions(QChart::SeriesAnimations);
1426 QStringList categories;
1427 for (int j=0; j<timeseriesset->at(0).size(); j++)
1428 categories << QString::fromStdString(timeseriesset->Label(j));
1429
1430 auto axisX = new QBarCategoryAxis;
1431 axisX->append(categories);
1432 chart->addAxis(axisX, Qt::AlignBottom);
1433 series->attachAxis(axisX);
1434 auto axisY = new QValueAxis;
1435 chart->addAxis(axisY, Qt::AlignLeft);
1436 series->attachAxis(axisY);
1437
1438 QString xAxisTitle = x_axis_title;
1439 QString yAxisTitle = y_axis_title;
1440 if (x_axis_title.isEmpty()) xAxisTitle = "Value";
1441 if (y_axis_title.isEmpty()) yAxisTitle = "Sample";
1442
1443 chart->legend()->setVisible(true);
1444 chart->legend()->setAlignment(Qt::AlignBottom);
1445
1446
1447 return true;
1448
1449}
1450
1452{
1453 QRect rect = QDialog::frameGeometry();
1454
1455 QString fileName = QFileDialog::getSaveFileName(this,
1456 tr("Save"), "",
1457 tr("png file (*.png)"));
1458
1459 if (!fileName.contains("."))
1460 fileName+=".png";
1461 chart->setAnimationOptions(QChart::NoAnimation);
1462 this->resize(rect.width() * 2, rect.height() * 2);
1463
1464 chartView->grab().save(fileName);
1465 this->resize(rect.size());
1466}
1467
1468
1470 double centerX, double centerY,
1471 double semiMajorAxis, double semiMinorAxis,
1472 double rotationAngle, double interval
1473) {
1474 std::vector<QPointF> points;
1475
1476 // Iterate over the angle in the range [0, 2π] with the given interval
1477 for (double t = 0; t <= 2 * M_PI; t += interval) {
1478 // Parametric equations for rotated ellipse
1479 double x = centerX + semiMajorAxis * cos(t) * cos(rotationAngle)
1480 - semiMinorAxis * sin(t) * sin(rotationAngle);
1481 double y = centerY + semiMajorAxis * cos(t) * sin(rotationAngle)
1482 + semiMinorAxis * sin(t) * cos(rotationAngle);
1483 QPointF point(x,y);
1484 points.push_back(point);
1485 }
1486
1487
1488 return points;
1489}
Matrix class with labeled rows and columns for Chemical Mass Balance analysis.
Definition cmbmatrix.h:19
Collection of time series with labels and observed values.
string Label(unsigned int i) const
Gets label for time point (uses custom labels if set)
double ObservedValue(int i)
Gets observed value at specified index.
Collection of named CMBVectorSet objects for hierarchical data organization.
Collection of named CMBVector objects for multi-variable analysis.
double min() const
Finds the minimum value across all vectors.
double max() const
Finds the maximum value across all vectors.
Vector class with string labels for Chemical Mass Balance analysis.
Definition cmbvector.h:17
vector< string > Labels() const
Gets all element labels.
Definition cmbvector.h:138
Definition chart.h:14
Source contribution container for Chemical Mass Balance results.
Manages a collection of elemental profiles (samples) for source fingerprinting analysis.
vector< string > GetElementNames() const
Get all element names (from first profile)
double GetMinimum() const
Get minimum concentration across all elements and samples.
double GetMaximum() const
Get maximum concentration across all elements and samples.
Container for elemental concentration data of a single sediment sample.
double GetMaximum() const
Get maximum concentration value.
vector< string > GetElementNames() const
Get list of all element names.
double GetMinimum() const
Get minimum concentration value.
bool PlotTimeSeriesSet_Stacked(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title, const QString &y_axis_title="")
bool PlotDistribution(TimeSeries< double > *mlr, const QString &variable)
bool PlotRangeSet(RangeSet *rangeset, const QString &title, const QString &x_axis_title, const QString &y_axis_title)
void onDistributionsVariableChanged(int)
bool PlotMatrix(CMBMatrix *matrix, const QString &title)
bool InitializeDistributions(CMBTimeSeriesSet *distributions, const QString &title)
bool PlotProfileSet(Elemental_Profile_Set *elementalprofileset, const QString &title)
QComboBox * source1_combo
bool PlotScatter(CMBMatrix *matrix)
ChartView * chartView
bool PlotContribution(Contribution *contributions, const QString &title)
void onMCMCVariableChanged(int)
Chart * chart
bool PlotVectorSet(CMBVectorSet *profile, const QString &title)
GeneralChart(QWidget *parent=nullptr)
bool PlotMCMCSamples(TimeSeries< double > *mlr, const QString &variable)
QComboBox * source2_combo
std::vector< QPointF > calculateRotatedEllipsePoints(double centerX, double centerY, double semiMajorAxis, double semiMinorAxis, double rotationAngle, double interval)
void onIndependentChanged(int i_independent)
bool PlotRegression(MultipleLinearRegression *timeseriesset, const QString &independent_var)
QComboBox * element_combo
bool PlotTimeSeriesSet(CMBTimeSeriesSet *regressionset, const QString &title, const QString &x_axis_title="", const QString &y_axis_title="")
bool PlotPredictedConcentration(Elemental_Profile *elemental_profile, const QString &title)
bool PlotVectorSetSet(CMBVectorSetSet *profile, const QString &title)
ResultItem * result_item
Ui::GeneralChart * ui
QComboBox * independent_combo
void onPairChanged(int pair_id)
bool Plot(ResultItem *res)
bool PlotTimeSeriesSet_M(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title="", const QString &y_axis_title="")
void onDFAPairChanged(int pair_id)
void onElementChanged(int i_constituent)
bool PlotVector(CMBVector *profile, const QString &title)
bool PlotRegressionSet(MultipleLinearRegressionSet *regressionset, const QString &title)
bool PlotTimeSeriesSet_A(CMBTimeSeriesSet *timeseriesset, const QString &title, const QString &x_axis_title="", const QString &y_axis_title="")
bool InitializeMCMCSamples(CMBTimeSeriesSet *mcmcsamples, const QString &title)
string XAxisTitle()
Definition resultitem.h:55
string Name() const
Definition resultitem.h:22
double YLimit(_range highlow)
Definition resultitem.h:59
result_type Type() const
Definition resultitem.h:24
string YAxisTitle()
Definition resultitem.h:56
Interface * Result() const
Definition resultitem.h:17
bool AbsValue()
Definition resultitem.h:58
bool FixedYLimit()
Definition resultitem.h:74
yaxis_mode YAxisMode()
Definition resultitem.h:27
double roundDown(double a, double rounding_value)
double roundDown(double a, double rounding_number=1.0)
@ low
Lower bound of the parameter range.
@ high
Upper bound of the parameter range.
@ distribution_with_observed
@ predicted_concentration
@ rangeset_with_observed
@ elemental_profile_set
@ timeseries_set_first_symbol