Commit 874e2bdd authored by Lefebvre, Jordan's avatar Lefebvre, Jordan
Browse files

radixplot removal

parent affa63e4
......@@ -12,7 +12,6 @@ TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
glls radixglls SS OPTIONAL
io radixio SS OPTIONAL
geometry radixgeometry SS OPTIONAL
plot radixplot SS OPTIONAL
sparsegrids radixsparsegrids SS OPTIONAL
widgets radixwidgets SS OPTIONAL
ams radixams SS OPTIONAL
......
##---------------------------------------------------------------------------##
## radixplot/CMakeLists.txt
## Jordan P. Lefebvre
## Tuesday May 31 12:50:40 2016
##---------------------------------------------------------------------------##
## CMAKE for radixplot
##---------------------------------------------------------------------------##
TRIBITS_SUBPACKAGE(plot)
##---------------------------------------------------------------------------##
## PACKAGE CONFIGURE FILE
##---------------------------------------------------------------------------##
##---------------------------------------------------------------------------##
## HEADER AND SOURCE FILES
##---------------------------------------------------------------------------##
# C/C++ headers
SET(MOC_HEADERS
plot.hh
)
SET(HEADERS
graph2d.hh
${MOC_HEADERS}
)
#
# Moc the header files
#
IF(USE_QT4)
QT4_WRAP_CPP(MOC_FILES
${MOC_HEADERS}
)
#
# Process qt resource files
QT4_ADD_RESOURCES(RESOURCE_RESULT
${RESOURCE_FILES}
)
ELSE()
QT5_WRAP_CPP(MOC_FILES
${MOC_HEADERS}
)
#
# Process qt resource files
QT5_ADD_RESOURCES(RESOURCE_RESULT
${RESOURCE_FILES}
)
ENDIF()
# C/C++ source
SET(SOURCES
plot.cc
graph2d.cc
)
SET(RESOURCE_FILES
plot.qrc
)
##---------------------------------------------------------------------------##
## PACKAGE TARGETS AND INSTALL
##---------------------------------------------------------------------------##
TRIBITS_ADD_LIBRARY(
radixplot
SOURCES ${SOURCES} ${MOC_FILES} ${RESOURCE_RESULT}
)
INSTALL(FILES ${HEADERS}
DESTINATION include/radixplot)
#
# Add test directory for this package
#
#TRIBITS_ADD_TEST_DIRECTORIES(tests)
#
# Add example directory for this package
#
TRIBITS_ADD_EXAMPLE_DIRECTORIES(examples)
TRIBITS_SUBPACKAGE_POSTPROCESS()
##---------------------------------------------------------------------------##
## end of radixplot/CMakeLists.txt
##---------------------------------------------------------------------------##
##---------------------------------------------------------------------------##
## radixplot/cmake/Dependencies.cmake
## Jordan P. Lefebvre
## Tuesday May 31 12:57:18 2016
##---------------------------------------------------------------------------##
IF(NOT USE_QT5)
SET(USE_QT4 ON)
ENDIF()
IF(USE_QT4)
SET(QT_PACKAGES QT)
ELSE()
SET(QT_PACKAGES Qt5Widgets Qt5Core)
ENDIF()
TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
LIB_REQUIRED_PACKAGES QtSolutions QCustomPlot
LIB_REQUIRED_TPLS ${QT_PACKAGES}
)
##---------------------------------------------------------------------------##
## end of radixplot/cmake/Dependencies.cmake
##---------------------------------------------------------------------------##
# Provide access to QT-generated code
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
IF(USE_QT4)
QT4_WRAP_CPP(QMOC_FILES
mainwindow.hh
)
ELSE()
QT5_WRAP_CPP(QMOC_FILES
mainwindow.hh
)
ENDIF()
SET(SOURCE
mainwindow.cc
)
TRIBITS_ADD_EXECUTABLE(plot2d-examples
NOEXEPREFIX
SOURCES ${SOURCE} ${QMOC_FILES}
)
/*
* @file: mainwindow.cpp
* @author: Jordan P. Lefebvre, lefebvrejp@ornl.gov
*
* Created on May 31, 2016, 10:52 PM
*/
#include "mainwindow.hh"
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QListView>
#include <QMessageBox>
#include <QMetaEnum>
#include <QScreen>
#include <QSplitter>
#include <QStandardItemModel>
#include <QVBoxLayout>
#include <cstdlib>
#include <limits>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setGeometry(400, 250, 542, 390);
QWidget *mainWidget = new QWidget(this);
plotWidget = new QWidget(this);
setCentralWidget(mainWidget);
QVBoxLayout *layout = new QVBoxLayout(mainWidget);
QVBoxLayout *plotLayout = new QVBoxLayout(plotWidget);
plot = new radix::Plot(this);
QListView *demoListView = new QListView(this);
QStandardItemModel *viewModel = new QStandardItemModel();
demoListView->setModel(viewModel);
viewModel->appendRow(new QStandardItem("Quadratic Demo"));
viewModel->appendRow(new QStandardItem("Simple Demo"));
viewModel->appendRow(new QStandardItem("Sinc Demo"));
viewModel->appendRow(new QStandardItem("Scatter Style Demo"));
viewModel->appendRow(new QStandardItem("Line Style Demo"));
viewModel->appendRow(new QStandardItem("Discontinuous Line Demo"));
viewModel->appendRow(new QStandardItem("Date Demo"));
// split between demo list and plot
QSplitter *split = new QSplitter();
// add demo list
split->addWidget(demoListView);
// add the plot widget
plotLayout->addWidget(plot);
split->addWidget(plotWidget);
split->setStretchFactor(0, 0);
split->setStretchFactor(1, 1);
layout->addWidget(split);
//
// Connect signals
//
connect(demoListView->selectionModel(),
SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this,
SLOT(changeDemo(QModelIndex, QModelIndex)));
demoListView->setCurrentIndex(viewModel->index(0, 0));
}
void MainWindow::changeDemo(const QModelIndex &current,
const QModelIndex &preivous)
{
int demoIndex = current.row();
// stop timer
// clear existing plot data
delete plot;
plot = new radix::Plot(plotWidget);
plotWidget->layout()->addWidget(plot);
if (dataTimer.isActive())
{
disconnect(&dataTimer, SLOT(timeout()));
dataTimer.stop();
}
//
// reset axes
//
plot->rescaleAxes();
plot->replot();
switch (demoIndex)
{
case 0:
setupQuadraticDemo();
break;
case 1:
setupSimpleDemo();
break;
case 2:
setupSincScatterDemo();
break;
case 3:
setupScatterStyleDemo();
break;
case 4:
setupLineStyleDemo();
break;
case 5:
setupDiscontinuousLineDemo();
break;
case 6:
setupDateDemo();
break;
}
setWindowTitle("QCustomPlot: " + demoName);
currentDemoIndex = demoIndex;
plot->replot();
}
void MainWindow::setupQuadraticDemo()
{
demoName = "Quadratic Demo";
// generate some data:
std::vector<double> x(101), y(101); // initialize with entries 0..100
for (size_t i = 0; i < 101; ++i)
{
x[i] = i / 50.0 - 1; // x goes from -1 to 1
y[i] = x[i] * x[i]; // let's plot a quadratic function
}
// create graph and assign data to it:
radix::Graph2D::SP sp_graph = plot->createGraph2D();
// graph will have the default key/value units
sp_graph->setData(x, y);
sp_graph->setKeyUnit("Seconds");
sp_graph->setValueUnit("eV");
plot->xAxis()->setLabel(sp_graph->getKeyUnit());
plot->yAxis()->setLabel(sp_graph->getValueUnit());
plot->rescaleAxes();
//
// Show xaxis subgrid
//
plot->xAxis()->grid()->setSubGridVisible(true);
}
void MainWindow::setupSimpleDemo()
{
demoName = "Simple Demo";
// add two new graphs and set their look:
radix::Graph2D::SP sp_graph0 = plot->createGraph2D();
// line color blue for first graph
sp_graph0->setPen(QPen(Qt::blue));
// first graph will be filled with translucent blue
sp_graph0->setBrush(QBrush(QColor(0, 0, 255, 20)));
radix::Graph2D::SP sp_graph1 = plot->createGraph2D();
sp_graph1->setPen(QPen(Qt::red)); // line color red for second graph
// generate some points of data (y0 for first, y1 for second graph):
std::vector<double> x(250), y0(250), y1(250);
for (int i = 0; i < 250; ++i)
{
x[i] = i;
y0[i] = qExp(-i / 150.0) * qCos(i / 10.0); // exponentially decaying cosine
y1[i] = qExp(-i / 150.0); // exponential envelope
}
// configure right and top axis to show ticks but no labels:
// (see QCPAxisRect::setupFullAxesBox for a quicker method to do this)
plot->xAxis2()->setVisible(true);
plot->xAxis2()->setTickLabels(false);
plot->yAxis2()->setVisible(true);
plot->yAxis2()->setTickLabels(false);
// make left and bottom axes always transfer their ranges to right
// and top axes:
connect(plot->xAxis(), SIGNAL(rangeChanged(QCPRange)), plot->xAxis2(),
SLOT(setRange(QCPRange)));
connect(plot->yAxis(), SIGNAL(rangeChanged(QCPRange)), plot->yAxis2(),
SLOT(setRange(QCPRange)));
// pass data points to graphs:
sp_graph0->setData(x, y0);
sp_graph1->setData(x, y1);
// let the ranges scale themselves so graph 0 fits perfectly
// in the visible area:
sp_graph0->rescaleAxes();
// same thing for graph 1, but only enlarge ranges
// (in case graph 1 is smaller than graph 0):
sp_graph1->rescaleAxes(true);
// Note: we could have also just called qcplot->rescaleAxes(); instead
// Allow user to drag axis ranges with mouse, zoom with mouse wheel
// and select graphs by clicking:
plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom |
QCP::iSelectPlottables);
}
void MainWindow::setupSincScatterDemo()
{
demoName = "Sinc Scatter Demo";
plot->legend()->setFont(QFont("Helvetica", 9));
// set locale to english, so we get english decimal separator:
plot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));
// add confidence band graphs:
radix::Graph2D::SP sp_graph1 = plot->createGraph2D();
QPen pen;
pen.setStyle(Qt::DotLine);
pen.setWidth(1);
pen.setColor(QColor(180, 180, 180));
sp_graph1->setName("Confidence Band 68%");
sp_graph1->setPen(pen);
sp_graph1->setBrush(QBrush(QColor(255, 50, 30, 20)));
radix::Graph2D::SP sp_graph2 = plot->createGraph2D();
//
// don't show two confidence band graphs in legend, so remove one
//
plot->legend()->removeItem(plot->legend()->itemCount() - 1);
sp_graph2->setPen(pen);
sp_graph1->setChannelFillGraph(*(sp_graph2.get()));
// add theory curve graph:
radix::Graph2D::SP sp_graph3 = plot->createGraph2D();
pen.setStyle(Qt::DashLine);
pen.setWidth(2);
pen.setColor(Qt::red);
sp_graph3->setPen(pen);
sp_graph3->setName("Theory Curve");
// add data point graph:
radix::Graph2D::SP sp_graph4 = plot->createGraph2D();
sp_graph4->setPen(QPen(Qt::blue));
sp_graph4->setLineStyle(QCPGraph::lsNone);
sp_graph4->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCross, 4));
sp_graph4->setErrorType(QCPGraph::etValue);
sp_graph4->setErrorPen(QPen(QColor(180, 180, 180)));
sp_graph4->setName("Measurement");
//
// generate ideal sinc curve data and some randomly perturbed data
// for scatter plot:
//
std::vector<double> x0(250), y0(250);
std::vector<double> yConfUpper(250), yConfLower(250);
for (size_t i = 0; i < 250; ++i)
{
//
// by adding a small offset(0.01) we make sure not do divide by zero
//
x0[i] = (i / 249.0 - 0.5) * 30 + 0.01;
y0[i] = qSin(x0[i]) / x0[i]; // sinc function
yConfUpper[i] = y0[i] + 0.15;
yConfLower[i] = y0[i] - 0.15;
x0[i] *= 1000;
}
std::vector<double> x1(50), y1(50), y1err(50);
for (size_t i = 0; i < 50; ++i)
{
// generate a gaussian distributed random number:
double tmp1 = rand() / (double)RAND_MAX;
double tmp2 = rand() / (double)RAND_MAX;
//
// box-muller transform for gaussian distribution
double r = qSqrt(-2 * qLn(tmp1)) * qCos(2 * M_PI * tmp2);
//
// set y1 to value of y0 plus a random gaussian pertubation:
//
x1[i] = ((std::rand() % 50) / 50.0 - 0.5) * 30 + 0.25;
y1[i] = qSin(x1[i]) / x1[i] + r * 0.15;
x1[i] *= 1000;
y1err[i] = 0.15;
}
std::sort(x1.begin(), x1.end());
//
// pass data to graphs and let QCustomPlot
// determine the axes ranges so the whole thing is visible:
//
sp_graph1->setData(x0, yConfUpper);
sp_graph2->setData(x0, yConfLower);
sp_graph3->setData(x0, y0);
sp_graph4->setDataValueError(x1, y1, y1err);
sp_graph3->rescaleAxes();
sp_graph4->rescaleAxes(true);
// setup look of bottom tick labels:
plot->xAxis()->setTickLabelRotation(30);
plot->xAxis()->setAutoTickCount(9);
plot->xAxis()->setNumberFormat("ebc");
plot->xAxis()->setNumberPrecision(1);
plot->xAxis()->moveRange(-10);
// make top right axes clones of bottom left axes. Looks prettier:
plot->axisRect()->setupFullAxesBox();
}
void MainWindow::setupScatterStyleDemo()
{
demoName = "Scatter Style Demo";
plot->legend()->setVisible(true);
plot->legend()->setFont(QFont("Helvetica", 9));
plot->legend()->setRowSpacing(-3);
//
// Create list of all possible scatter styles and one custom option
//
QVector<QCPScatterStyle::ScatterShape> shapes;
shapes << QCPScatterStyle::ssCross;
shapes << QCPScatterStyle::ssPlus;
shapes << QCPScatterStyle::ssCircle;
shapes << QCPScatterStyle::ssDisc;
shapes << QCPScatterStyle::ssSquare;
shapes << QCPScatterStyle::ssDiamond;
shapes << QCPScatterStyle::ssStar;
shapes << QCPScatterStyle::ssTriangle;
shapes << QCPScatterStyle::ssTriangleInverted;
shapes << QCPScatterStyle::ssCrossSquare;
shapes << QCPScatterStyle::ssPlusSquare;
shapes << QCPScatterStyle::ssCrossCircle;
shapes << QCPScatterStyle::ssPlusCircle;
shapes << QCPScatterStyle::ssPeace;
shapes << QCPScatterStyle::ssCustom;
QPen pen;
//
// add graphs with different scatter styles:
//
for (int i = 0; i < shapes.size(); ++i)
{
radix::Graph2D::SP graph = plot->createGraph2D();
pen.setColor(QColor(qSin(i * 0.3) * 100 + 100,
qSin(i * 0.6 + 0.7) * 100 + 100,
qSin(i * 0.4 + 0.6) * 100 + 100));
//
// generate data:
//
std::vector<double> x(10), y(10);
for (size_t k = 0; k < 10; ++k)
{
x[k] = k / 10.0 * 4 * 3.14 + 0.01;
y[k] = 7 * qSin(x[k]) / x[k] + (shapes.size() - i) * 5;
}
graph->setData(x, y);
graph->rescaleAxes(true);
graph->setPen(pen);
// use static meta object data from scatter style to get its name
graph->setName(
QCPScatterStyle::staticMetaObject
.enumerator(QCPScatterStyle::staticMetaObject.indexOfEnumerator(
"ScatterShape"))
.valueToKey(shapes.at(i)));
graph->setLineStyle(QCPGraph::lsLine);
//
// set scatter style:
//
if (shapes.at(i) != QCPScatterStyle::ssCustom)
{
graph->setScatterStyle(QCPScatterStyle(shapes.at(i), 10));
}
else
{
//
// Make custom scatter style
//
QPainterPath customScatterPath;
for (int i = 0; i < 3; ++i)
customScatterPath.cubicTo(qCos(2 * M_PI * i / 3.0) * 9,
qSin(2 * M_PI * i / 3.0) * 9,
qCos(2 * M_PI * (i + 0.9) / 3.0) * 9,
qSin(2 * M_PI * (i + 0.9) / 3.0) * 9, 0, 0);
graph->setScatterStyle(QCPScatterStyle(
customScatterPath, QPen(Qt::black, 0), QColor(40, 70, 255, 50), 10));
}
}
//
// set blank axis lines:
//
plot->rescaleAxes();
plot->xAxis()->setTicks(false);
plot->yAxis()->setTicks(false);
plot->xAxis()->setTickLabels(false);
plot->yAxis()->setTickLabels(false);
//
// make top right axes clones of bottom left axes:
//
plot->axisRect()->setupFullAxesBox();
}
void MainWindow::setupLineStyleDemo()
{
demoName = "Line Style Demo";
plot->legend()->setVisible(true);
plot->legend()->setFont(QFont("Helvetica", 9));
QPen pen;
QStringList lineNames;
lineNames << "lsNone"
<< "lsLine"
<< "lsStepLeft"
<< "lsStepRight"
<< "lsStepCenter"
<< "lsImpulse";
//
// add graphs with different line styles:
//
for (int i = QCPGraph::lsNone; i <= QCPGraph::lsImpulse; ++i)
{
radix::Graph2D::SP graph = plot->createGraph2D();
pen.setColor(QColor(qSin(i * 1 + 1.2) * 80 + 80,
qSin(i * 0.3 + 0) * 80 + 80,
qSin(i * 0.3 + 1.5) * 80 + 80));
graph->setPen(pen);
graph->setName(lineNames.at(i - QCPGraph::lsNone).toStdString());
graph->setLineStyle((QCPGraph::LineStyle)i);
graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));
//
// generate data:
//
std::vector<double> x(15), y(15);
for (int j = 0; j < 15; ++j)
{
x[j] = j / 15.0 * 5 * 3.14 + 0.01;
// use QCP line style enums to ensure graphs to not overlap
y[j] = 7 * qSin(x[j]) / x[j] - (i - QCPGraph::lsNone) * 5 +
(QCPGraph::lsImpulse)*5 + 2;
}
graph->setData(x, y);
graph->rescaleAxes(true);
}
//
// zoom out a bit:
//
plot->yAxis()->scaleRange(1.1, plot->yAxis()->range().center());
plot->xAxis()->scaleRange(1.1, plot->xAxis()->range().center());
//
// set blank axis lines:
//
plot->xAxis()->setTicks(false);
plot->yAxis()->setTicks(true);
plot->xAxis()->setTickLabels(false);
plot->yAxis()->setTickLabels(true);
//
// make top right axes clones of bottom left axes:
//
plot->axisRect()->setupFullAxesBox();
}
void MainWindow::setupDiscontinuousLineDemo()
{
demoName = "Discontinuous Line Demo";
plot->legend()->setVisible(true);
plot->legend()->setFont(QFont("Helvetica", 9));
QPen pen;
QStringList lineNames;
lineNames << "lsNone"
<< "lsLine"
<< "lsStepLeft"
<< "lsStepRight"
<< "lsStepCenter"
<< "lsImpulse";
//
// add graphs with different line styles:
//
for (int i = QCPGraph::lsNone; i <= QCPGraph::lsStepCenter; ++i)
{
radix::Graph2D::SP graph = plot->createGraph2D();
pen.setColor(QColor(qSin(i * 1 + 1.2) * 80 + 80,
qSin(i * 0.3 + 0) * 80 + 80,
qSin(i * 0.3 + 1.5) * 80 + 80));
graph->setPen(pen);
graph->setName(lineNames.at(i - QCPGraph::lsNone).toStdString());
graph->setLineStyle((QCPGraph::LineStyle)i);
graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));
//
// generate data:
//
std::vector<double> x(15), y(15);
for (int j = 0; j < 7; ++j)
{