RInside Version 0.2.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
qtdensity.cpp
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // Qt usage example for RInside, inspired by the standard 'density
4 // sliders' example for other GUI toolkits -- this time with SVG
5 //
6 // Copyright (C) 2011 - 2013 Dirk Eddelbuettel and Romain Francois
7 
8 #include "qtdensity.h"
9 
11 {
12  m_bw = 100; // initial bandwidth, will be scaled by 100 so 1.0
13  m_kernel = 0; // initial kernel: gaussian
14  m_cmd = "c(rnorm(100,0,1), rnorm(50,5,1))"; // simple mixture
15  m_R["bw"] = m_bw; // pass bandwidth to R, and have R compute a temp.file name
16  m_tempfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("tfile <- tempfile()")));
17  m_svgfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("sfile <- tempfile()")));
18  setupDisplay();
19 }
20 
22  QWidget *window = new QWidget;
23  window->setWindowTitle("Qt and RInside demo: density estimation");
24 
25  QSpinBox *spinBox = new QSpinBox;
26  QSlider *slider = new QSlider(Qt::Horizontal);
27  spinBox->setRange(5, 200);
28  slider->setRange(5, 200);
29  QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
30  QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
31  spinBox->setValue(m_bw);
32  QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(getBandwidth(int)));
33 
34  QLabel *cmdLabel = new QLabel("R command for random data creation");
35  QLineEdit *cmdEntry = new QLineEdit(m_cmd);
36  QObject::connect(cmdEntry, SIGNAL(textEdited(QString)), this, SLOT(getRandomDataCmd(QString)));
37  QObject::connect(cmdEntry, SIGNAL(editingFinished()), this, SLOT(runRandomDataCmd()));
38 
39  QGroupBox *kernelRadioBox = new QGroupBox("Density Estimation kernel");
40  QRadioButton *radio1 = new QRadioButton("&Gaussian");
41  QRadioButton *radio2 = new QRadioButton("&Epanechnikov");
42  QRadioButton *radio3 = new QRadioButton("&Rectangular");
43  QRadioButton *radio4 = new QRadioButton("&Triangular");
44  QRadioButton *radio5 = new QRadioButton("&Cosine");
45  radio1->setChecked(true);
46  QVBoxLayout *vbox = new QVBoxLayout;
47  vbox->addWidget(radio1);
48  vbox->addWidget(radio2);
49  vbox->addWidget(radio3);
50  vbox->addWidget(radio4);
51  vbox->addWidget(radio5);
52  kernelRadioBox->setMinimumSize(260,140);
53  kernelRadioBox->setMaximumSize(260,140);
54  kernelRadioBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
55  kernelRadioBox->setLayout(vbox);
56 
57  QButtonGroup *kernelGroup = new QButtonGroup;
58  kernelGroup->addButton(radio1, 0);
59  kernelGroup->addButton(radio2, 1);
60  kernelGroup->addButton(radio3, 2);
61  kernelGroup->addButton(radio4, 3);
62  kernelGroup->addButton(radio5, 4);
63  QObject::connect(kernelGroup, SIGNAL(buttonClicked(int)), this, SLOT(getKernel(int)));
64 
65  m_svg = new QSvgWidget();
66  runRandomDataCmd(); // also calls plot()
67 
68  QGroupBox *estimationBox = new QGroupBox("Density estimation bandwidth (scaled by 100)");
69  QHBoxLayout *spinners = new QHBoxLayout;
70  spinners->addWidget(spinBox);
71  spinners->addWidget(slider);
72  QVBoxLayout *topright = new QVBoxLayout;
73  topright->addLayout(spinners);
74  topright->addWidget(cmdLabel);
75  topright->addWidget(cmdEntry);
76  estimationBox->setMinimumSize(360,140);
77  estimationBox->setMaximumSize(360,140);
78  estimationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
79  estimationBox->setLayout(topright);
80  QHBoxLayout *upperlayout = new QHBoxLayout;
81  upperlayout->addWidget(kernelRadioBox);
82  upperlayout->addWidget(estimationBox);
83 
84  QHBoxLayout *lowerlayout = new QHBoxLayout;
85  lowerlayout->addWidget(m_svg);
86 
87  QVBoxLayout *outer = new QVBoxLayout;
88  outer->addLayout(upperlayout);
89  outer->addLayout(lowerlayout);
90  window->setLayout(outer);
91  window->show();
92 }
93 
94 void QtDensity::plot(void) {
95  const char *kernelstrings[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" };
96  m_R["bw"] = m_bw;
97  m_R["kernel"] = kernelstrings[m_kernel]; // that passes the string to R
98  std::string cmd0 = "svg(width=6,height=6,pointsize=10,filename=tfile); ";
99  std::string cmd1 = "plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: ";
100  std::string cmd2 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()";
101  std::string cmd = cmd0 + cmd1 + kernelstrings[m_kernel] + cmd2; // stick the selected kernel in the middle
102  m_R.parseEvalQ(cmd);
103  filterFile(); // we need to simplify the svg file for display by Qt
104  m_svg->load(m_svgfile);
105 }
106 
108  if (bw != m_bw) {
109  m_bw = bw;
110  plot();
111  }
112 }
113 
114 void QtDensity::getKernel(int kernel) {
115  if (kernel != m_kernel) {
116  m_kernel = kernel;
117  plot();
118  }
119 }
120 
121 void QtDensity::getRandomDataCmd(QString txt) {
122  m_cmd = txt;
123 }
124 
126  std::string cmd = "y2 <- " + m_cmd.toStdString() + "; y <- y2";
127  m_R.parseEvalQNT(cmd);
128  plot(); // after each random draw, update plot with estimate
129 }
130 
132  // cairoDevice creates richer SVG than Qt can display
133  // but per Michaele Lawrence, a simple trick is to s/symbol/g/ which we do here
134  QFile infile(m_tempfile);
135  infile.open(QFile::ReadOnly);
136  QFile outfile(m_svgfile);
137  outfile.open(QFile::WriteOnly | QFile::Truncate);
138 
139  QTextStream in(&infile);
140  QTextStream out(&outfile);
141  QRegExp rx1("<symbol");
142  QRegExp rx2("</symbol");
143  while (!in.atEnd()) {
144  QString line = in.readLine();
145  line.replace(rx1, "<g"); // so '<symbol' becomes '<g ...'
146  line.replace(rx2, "</g");// and '</symbol becomes '</g'
147  out << line << "\n";
148  }
149  infile.close();
150  outfile.close();
151 }
RInside & m_R
Definition: qtdensity.h:47
void getKernel(int kernel)
Definition: qtdensity.cpp:114
int m_bw
Definition: qtdensity.h:50
QString m_svgfile
Definition: qtdensity.h:49
QSvgWidget * m_svg
Definition: qtdensity.h:46
void getRandomDataCmd(QString txt)
Definition: qtdensity.cpp:121
void parseEvalQ(const std::string &line)
Definition: RInside.cpp:366
QString m_tempfile
Definition: qtdensity.h:48
void runRandomDataCmd(void)
Definition: qtdensity.cpp:125
void plot(void)
Definition: qtdensity.cpp:94
int parseEval(const std::string &line, SEXP &ans)
Definition: RInside.cpp:308
int m_kernel
Definition: qtdensity.h:50
void setupDisplay(void)
Definition: qtdensity.cpp:21
QtDensity(RInside &R)
Definition: qtdensity.cpp:10
void parseEvalQNT(const std::string &line)
Definition: RInside.cpp:374
void filterFile(void)
Definition: qtdensity.cpp:131
QString m_cmd
Definition: qtdensity.h:51
void getBandwidth(int bw)
Definition: qtdensity.cpp:107