JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
Loading...
Searching...
No Matches
Example (JKQTPlotter): Wiggle Plots

This project (see ./examples/wiggleplots/) demonstrates how to draw "wiggle plots" with JKQtPlotter, using JKQTPFilledCurveXGraph or JKQTPFilledCurveYGraph. Wiggle plots are plots, where the fill color is different above and below the baseline of the plot. They are e.g. used in seismology.

The source code of the main application can be found in wiggleplots.cpp. If creates two different plots that demonstrate two styles of plots and also uses the horizontal and vertical variant of the graph class.

Plot red/blue wiggle plot using <tt>JKQTPFilledCurveXGraph</tt>

For the first example we simulate a 1D random walk and plot the result as a filles wiggle plot:

In a first step, we obtain a pointer to the JKQTPDatastore and add two columns to it.

// 1. get a pointer to the internal datastore (for convenience)
JKQTPDatastore* ds=plot.getDatastore();
// 2. now we create 2 datacolumns with length 1000 (NSteps) entries in the datastore
// these will later hold the time-step and position of a random walker
const size_t NSteps=400;
const size_t columnT=ds->addLinearColumn(NSteps, 0, NSteps-1, "time");
const size_t columnX=ds->addColumn(NSteps, "position");
This class manages data columns (with entries of type double ), used by JKQTPlotter/JKQTBasePlotter t...
Definition jkqtpdatastorage.h:282
size_t addLinearColumn(size_t rows, double start, double end, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at st...
size_t addColumn(JKQTPColumn col)
add a new column to the datastore and return its ID

Now we fill the column with the random walk data:

// 3. now we simulate a simple rendom walk and store the calculated positions
// in columnX
double pos=5;
const double stepsize=1;
std::random_device rd; // random number generators:
std::mt19937 gen{rd()};
std::uniform_int_distribution<int> dist(0,1);
for (size_t t=0; t<NSteps; t++) {
ds->set(columnX, t, pos);
pos=pos+stepsize*(static_cast<double>(dist(gen))*2.0-1.0);
}
void set(size_t column, size_t row, double value)
sets the value at position (column, row). column is the logical column and will be mapped to the acco...
Definition jkqtpdatastorage.h:2700

Now we can generate the actual graph and set its basic properties and data columns:

// 4. now we add three semi-transparent, filled curve plots, one for each histogram
// 5. set graph titles
graph->setTitle("Random Walk");
// 6. set data
graph->setXColumn(columnT); graph->setYColumn(columnX);
This implements filled curve plots where the area is filled between the plot line and the x-Axis.
Definition jkqtpfilledcurve.h:103
virtual void setTitle(const QString &__value)
sets the title of the plot (for display in key!).
void setYColumn(int __value)
the column that contains the y-component of the datapoints
void setXColumn(int __value)
the column that contains the x-component of the datapoints

Now we can acrivate the wiggle plot style filling mode and set the fill colors and line color and width.

// 7.1 enable wiggle-plot filling
// 7.2 draw the data also as a black, thin line
graph->setLineColor(QColor("black"));
graph->setLineWidth(1);
// 7.3 fill areas below the baseline with red
graph->setFillColor(QColor("red"));
// 7.4 fill areas above the baseline with blue
graph->fillStyleBelow().setFillColor(QColor("blue"));
JKQTPGraphFillStyleMixin & fillStyleBelow()
if m_fillMode ==FillAboveAndBelowDifferently then this fill style is used below the baseline and the ...
@ TwoColorFilling
the area above and below baseline with the two different colors/patterns, generates "wiggle plots",...
Definition jkqtpfilledcurve.h:50
void setFillMode(JKQTPFilledCurveGraphBase::FillMode mode)
specifies how the area of the graph is filles
void setFillColor(const QColor &__value)
set the color of the graph filling
void setLineWidth(double __value)
set the line width of the graph line (in pt)
void setLineColor(const QColor &__value)
set the color of the graph line

The baseline is set to the starting point (5) of the random walk. By default it would be at y=0.

// 7.5 set the baseline to be at 5 (not the default 0
graph->setBaseline(5);
void setBaseline(double __value)
baseline of the plot (NOTE: 0 is interpreted as until plot border in log-mode!!!)

Now we only have to add the graph to the plotter and set some final properties for styling:

// 8. add the graphs to the plot, so they are actually displayed
plot.addGraph(graph);
// 9. set axis labels
plot.getXAxis()->setAxisLabel("time $t$");
plot.getYAxis()->setAxisLabel("walker position $x(t)$");
// 10. scale plot automatically
plot.zoomToFit();
// 11. show plotter and make it a decent size
plot.show();
plot.resize(600,400);

This is the resulting plot:

wiggleplot of random walk

Plot black/transparent wiggle plot using <tt>JKQTPFilledCurveYGraph</tt> in a "seismographic style"

The second example follows mor or less the same steps as above, but here we add several graphs that each show a wavepacket that is shoft slightly:

// 3. now we calculate several wavepackets and add a graph for each.
const size_t NWavepackets=7;
for (size_t nw=0; nw<NWavepackets; nw++) {
const size_t columnPacket=ds->addColumn(NSteps, "wavepacket1");
const double packwidth=0.4/static_cast<double>(NWavepackets);
const double pos=pow(static_cast<double>(nw), 0.6)*packwidth*3.5+5.0*packwidth;
const double wavelength=packwidth/1.5;
const double offset=(static_cast<double>(nw)*1.5+1.5);
for (size_t ti=0; ti<NSteps; ti++) {
const double t=ds->get(columnT, ti);
ds->set(columnPacket, ti, offset+sin(2.0*M_PI*t/wavelength)*exp(-0.5*jkqtp_sqr(t-pos)/jkqtp_sqr(packwidth)));
}
// 4. now we add three semi-transparent, filled curve plots, one for each histogram
// set graph titles
graph->setTitle("wave "+QString::number(nw+1));
// set data
graph->setYColumn(columnT); graph->setXColumn(columnPacket);
// enable wiggle-plot filling
// draw the data also as a black, thin line
graph->setLineColor(QColor("black"));
graph->setLineWidth(1);
// fill areas below the baseline with red
graph->setFillColor(Qt::transparent);
// fill areas above the baseline with blue
graph->fillStyleBelow().setFillColor(QColor("black"));
// set the baseline to be at 5 (not the default 0
graph->setBaseline(offset);
// add the graphs to the plot, so they are actually displayed
plot.addGraph(graph);
}
double get(size_t column, size_t row) const
returns the value at position (column, row). column is the logical column and will be mapped to the a...
Definition jkqtpdatastorage.h:2675
This implements filled curve plots where the area is filled between the plot line and y-Axis.
Definition jkqtpfilledcurve.h:210
T jkqtp_sqr(const T &v)
returns the quare of the value v, i.e. v*v
Definition jkqtpmathtools.h:327

Also the colors are different: We use black below the baseline and transparent above. The line through the data points is black as well.

This is the resulting plot:

wiggleplot of random walk