add example for pointilistic image plot, using a scatter plot

This commit is contained in:
Jan W. Krieger 2018-12-24 21:39:37 +01:00
parent efa079f17f
commit 877abaf2b8
16 changed files with 229 additions and 4 deletions

View File

@ -51,6 +51,7 @@ addSimpleTest(speed)
addSimpleTest(rgbimageplot_qt) addSimpleTest(rgbimageplot_qt)
addSimpleTest(impulsesplot) addSimpleTest(impulsesplot)
addSimpleTest(paramscatterplot) addSimpleTest(paramscatterplot)
addSimpleTest(paramscatterplot_image)
addSimpleTest(parametriccurve) addSimpleTest(parametriccurve)
addSimpleTest(parsedfunctionplot) addSimpleTest(parsedfunctionplot)
addSimpleTest(functionplot) addSimpleTest(functionplot)

View File

@ -32,6 +32,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_filledgraphs_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_filledgraphs) | [Filled Curve Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_filledgraphs) | `JKQTPbarVerticalGraph`<br/>setting/altering data in `JKQTPdatstore` directly<br/> transparent plots<br/>calculating histograms | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_filledgraphs_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_filledgraphs) | [Filled Curve Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_filledgraphs) | `JKQTPbarVerticalGraph`<br/>setting/altering data in `JKQTPdatstore` directly<br/> transparent plots<br/>calculating histograms |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_impulsesplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | [Impulse Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | `JKQTPimpulsesVerticalGraph` and `JKQTPimpulsesHorizontalGraph`<br/>C++-style QVector as plot data | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_impulsesplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | [Impulse Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | `JKQTPimpulsesVerticalGraph` and `JKQTPimpulsesHorizontalGraph`<br/>C++-style QVector as plot data |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | [Scatter Graph with Parametrized Symbols/Colors](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>modify scatter/points/line-graph properties by data | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | [Scatter Graph with Parametrized Symbols/Colors](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>modify scatter/points/line-graph properties by data |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_image_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot_image) | [Draw an Artistic Image with a Parametrized Scatter Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot_image) | `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>rectangular arrangement of scatters<br/>generative computer graphics |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parametriccurve_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | [Plotting Parametric Curves](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | `JKQTPxyLineGraph` and `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>parametric curve plotting | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parametriccurve_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | [Plotting Parametric Curves](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | `JKQTPxyLineGraph` and `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>parametric curve plotting |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_functionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_functionplot) | [Plotting Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_functionplot) | `JKQTPxFunctionLineGraph` <br/>diretly plotting C/C++-functions | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_functionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_functionplot) | [Plotting Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_functionplot) | `JKQTPxFunctionLineGraph` <br/>diretly plotting C/C++-functions |
[![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) | [Plotting Parsed Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) | `JKQTPxParsedFunctionLineGraph` <br/>plotting functions with the internal math equation parser/evaluator | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) | [Plotting Parsed Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) | `JKQTPxParsedFunctionLineGraph` <br/>plotting functions with the internal math equation parser/evaluator |

View File

@ -198,13 +198,13 @@ class LIB_EXPORT JKQTPxyParametrizedScatterGraph: public JKQTPxyLineGraph, publi
/** \brief this column contains the line width */ /** \brief this column contains the line width */
int linewidthColumn; int linewidthColumn;
/** \brief if the gridModeForSymbolSize mode is actiavted (false), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */ /** \brief if the gridModeForSymbolSize mode is actiavted (true), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */
bool gridModeForSymbolSize; bool gridModeForSymbolSize;
/** \brief if the gridModeForSymbolSize mode is actiavted (false), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */ /** \brief if the gridModeForSymbolSize mode is actiavted (true), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */
double gridDeltaX; double gridDeltaX;
/** \brief if the gridModeForSymbolSize mode is actiavted (false), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */ /** \brief if the gridModeForSymbolSize mode is actiavted (true), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */
double gridDeltaY; double gridDeltaY;
/** \brief if the gridModeForSymbolSize mode is actiavted (false), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */ /** \brief if the gridModeForSymbolSize mode is actiavted (true), the plot assumes that the scatter symbols are ordered in a grid. It the uses the given griDeltaX and gridDeltaY to calculate the symbol size, so they fill the available space to a fraction gridSymbolFractionSize. */
double gridSymbolFractionSize; double gridSymbolFractionSize;
/** \brief if this is true, the value in the colorColumn is converted to an integer, representing a color in ARGB format (as in QRgb) */ /** \brief if this is true, the value in the colorColumn is converted to an integer, representing a color in ARGB format (as in QRgb) */

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

View File

@ -0,0 +1,99 @@
[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/)
# JKQtPlotter
## Draw an Artistic Image with a Parametrized Scatter Graph
This project (see `./test/simpletest_paramscatterplot_image/`) demonstrates the capabilities of `JKQTPxyParametrizedScatterGraph` to display parametrized scatters in a rectangular arrangement. See the test program in [`test/simpletest_paramscatterplot`](https://github.com/jkriege2/JKQtPlotter/blob/master/test/simpletest_paramscatterplot) for a basic example of the capabilities of `JKQTPxyParametrizedScatterGraph`.
In this example, we load an image, convert it to greyscale and store it, together with x/y-coordinate-vectors in the datastore. Then a `JKQTPxyParametrizedScatterGraph` is used to draw the image as a pointilistic artwork, where each pixel is represented by a disk. The color of the disk is chosen from a color-palette, based on the grey-value. The size of each disk is chosen from the inverse grey value.
First we prepare the data, as described above. The image is loaded and then converted to the required data vectors.
```c++
// 2.1 load image
QImage image(":/example.bmp");
QVector<double> imageVector, pointSizes;
QVector<double> X,Y;
// 2.2 convert image to greyscale, stored in a vector in row-major order
double maxSymbolSize=30; // maximal diameter of symbols in pt
for (int y=0; y<image.height(); y++) {
for (int x=0; x<image.width(); x++) {
// calculate grey-value image vector
imageVector.push_back(qGray(image.pixel(x,y)));
// calculate point sizes from inverse grey value and scaling between 0 and maxSymbolSize
pointSizes.push_back(static_cast<double>(255-qGray(image.pixel(x,y)))/255.0*maxSymbolSize);
// calculate X/Y-coordinates (y mirrored, so image is upright)
X.push_back(x);
Y.push_back(image.height()-1-y);
}
}
// 2.3 and copy it to the datastore
size_t columnX=ds->addCopiedColumn(X, "x");
size_t columnY=ds->addCopiedColumn(Y, "y");
size_t columnG=ds->addCopiedColumn(imageVector, "greyscaleImageData");
size_t columnS=ds->addCopiedColumn(pointSizes, "pointSizes");
```
Now we can use th datavectors to add a `JKQTPxyParametrizedScatterGraph`:
```c++
JKQTPxyParametrizedScatterGraph* graph1=new JKQTPxyParametrizedScatterGraph(&plot);
graph1->set_xColumn(columnX);
graph1->set_yColumn(columnY);
graph1->set_sizeColumn(columnS);
graph1->set_symbol(JKQTPfilledCircle);
graph1->set_colorColumn(columnG);
graph1->set_palette(JKQTPMathImageMATLAB);
graph1->set_drawLine(false);
graph1->set_title("");
plot.addGraph(graph1);
```
For illustrative purposes, the original image is shown at the bottom-left:
```c++
JKQTPImage* graph2=new JKQTPImage(&plot);
graph2->set_image(image);
graph2->set_x(0);
graph2->set_y(0);
graph2->set_width(10);
graph2->set_height(10);
plot.addGraph(graph2);
```
Finally the plot is styled and the axis aspect ratios are fixed:
```c++
// scale the plot so the graph is contained and format the coordinate system
plot.getXAxis()->set_axisLabel("x-axis");
plot.getYAxis()->set_axisLabel("y-axis");
plot.getXAxis()->set_drawGrid(false);
plot.getYAxis()->set_drawGrid(false);
// max. size is the size of the image
plot.setXY(0,image.width()-1,0,image.height()-1);
plot.setAbsoluteXY(0,image.width()-1,0,image.height()-1);
// ensure that axis aspect ration and coordinate system aspect ratio are maintained
plot.get_plotter()->set_maintainAspectRatio(true);
plot.get_plotter()->set_aspectRatio(1);
plot.get_plotter()->set_maintainAxisAspectRatio(true);
plot.get_plotter()->set_axisAspectRatio(1);
```
The full test appication combines all these variants and the result looks like this:
![jkqtplotter_simpletest_paramscatterplot_image](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_image.png)
You can modify the example above in several ways, e.g. by choosing another symbol (e.g. a star):
![jkqtplotter_simpletest_paramscatterplot_image_star](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_image_star.png)
... or by changing the color palette and the symbol:
![jkqtplotter_simpletest_paramscatterplot_image_palette](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_image_palette.png)
![jkqtplotter_simpletest_paramscatterplot_image_palette_triangle](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_image_palette_triangle.png)
... or even to set a different symbol for each pixel, based on the values in `columnS` (simply add `graph1->set_symbolColumn(columnS)`):
![jkqtplotter_simpletest_paramscatterplot_image_varsymbol](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_image_varsymbol.png)
[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,86 @@
#include <QApplication>
#include "jkqtplotter/jkqtplotter.h"
#include "jkqtplotter/jkqtpgraphs.h"
#include "jkqtplotter/jkqtpgraphsimage.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
JKQtPlotter plot;
JKQTPdatastore* ds=plot.getDatastore();
// 2. Prepare Data
// 2.1 load image
QImage image(":/example.bmp");
QVector<double> imageVector, pointSizes;
QVector<double> X,Y;
// 2.2 convert image to greyscale, stored in a vector in row-major order
double maxSymbolSize=30; // maximal diameter of symbols in pt
for (int y=0; y<image.height(); y++) {
for (int x=0; x<image.width(); x++) {
// calculate grey-value image vector
imageVector.push_back(qGray(image.pixel(x,y)));
// calculate point sizes from inverse grey value and scaling between 0 and maxSymbolSize
pointSizes.push_back(static_cast<double>(255-qGray(image.pixel(x,y)))/255.0*maxSymbolSize);
// calculate X/Y-coordinates (y mirrored, so image is upright)
X.push_back(x);
Y.push_back(image.height()-1-y);
}
}
// 2.3 and copy it to the datastore
size_t columnX=ds->addCopiedColumn(X, "x");
size_t columnY=ds->addCopiedColumn(Y, "y");
size_t columnG=ds->addCopiedColumn(imageVector, "greyscaleImageData");
size_t columnS=ds->addCopiedColumn(pointSizes, "pointSizes");
// 3. add graphs to plot
// 3.1 Now add a parametrized scatter graph with columnX, columnY for the positions of the
// scatter points, where the symbol size is given by column columnS and the color of
// each symbol is set from column columnG, via a color palette JKQTPMathImageMATLAB
JKQTPxyParametrizedScatterGraph* graph1=new JKQTPxyParametrizedScatterGraph(&plot);
graph1->set_xColumn(columnX);
graph1->set_yColumn(columnY);
graph1->set_sizeColumn(columnS);
graph1->set_symbolColumn(columnS);
graph1->set_symbol(JKQTPfilledTriangle);
graph1->set_colorColumn(columnG);
graph1->set_palette(JKQTPMathImageOCEAN);
graph1->set_drawLine(false);
graph1->set_title("");
plot.addGraph(graph1);
// 3.2 add an image to display the original graphics
JKQTPImage* graph2=new JKQTPImage(&plot);
graph2->set_image(image);
graph2->set_x(0);
graph2->set_y(0);
graph2->set_width(10);
graph2->set_height(10);
plot.addGraph(graph2);
// 4. scale the plot so the graph is contained and format the coordinate system
plot.getXAxis()->set_axisLabel("x-axis");
plot.getYAxis()->set_axisLabel("y-axis");
plot.getXAxis()->set_drawGrid(false);
plot.getYAxis()->set_drawGrid(false);
// max. size is the size of the image
plot.setXY(0,image.width()-1,0,image.height()-1);
plot.setAbsoluteXY(0,image.width()-1,0,image.height()-1);
// ensure that axis aspect ration and coordinate system aspect ratio are maintained
plot.get_plotter()->set_maintainAspectRatio(true);
plot.get_plotter()->set_aspectRatio(1);
plot.get_plotter()->set_maintainAxisAspectRatio(true);
plot.get_plotter()->set_axisAspectRatio(1);
// 5. show plotter and make it a decent size
plot.show();
plot.resize(800,800);
return app.exec();
}

View File

@ -0,0 +1,25 @@
# source code for this simple demo
SOURCES = jkqtplotter_simpletest_paramscatterplot_image.cpp
RESOURCES += jkqtplotter_simpletest_paramscatterplot_image.qrc
# configure Qt
CONFIG += qt
QT += core gui xml svg
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
# output executable name
TARGET = jkqtplotter_simpletest_paramscatterplot_image
# include JKQtPlotter source code
DEPENDPATH += . ../../lib
INCLUDEPATH += ../../lib
CONFIG (debug, debug|release):LIBS += -L../../lib/debug -ljkqtplotterlib
CONFIG (release):LIBS += -L../../lib/release -ljkqtplotterlib
win32-msvc*: DEFINES += _USE_MATH_DEFINES
# here you can activate some debug options
#DEFINES += SHOW_JKQTPLOTTER_DEBUG
#DEFINES += JKQTBP_AUTOTIMER

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>example.bmp</file>
</qresource>
</RCC>

View File

@ -0,0 +1,8 @@
TEMPLATE = subdirs
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_paramscatterplot_image
jkqtplotterlib.file = ../../lib/jkqtplotterlib.pro
jkqtplotter_simpletest_paramscatterplot_image.file=$$PWD/jkqtplotter_simpletest_paramscatterplot_image.pro
jkqtplotter_simpletest_paramscatterplot_image.depends = jkqtplotterlib