diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 0931fd40ea..1edd04e4bd 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -122,6 +122,7 @@ if(JKQtPlotter_BUILD_EXAMPLES) # the basenames are applied to the windows in the order of their windowTitle()s! set(JKQTPlotter_GenerateDocScreenshots_From scatter/scatter,scatter_error + scatter_customsymbol simpletest barchart/barchart,barchart_hor wiggleplots/wiggleplot_x,wiggleplot_y @@ -151,6 +152,7 @@ if(JKQtPlotter_BUILD_EXAMPLES) impulsesplot parametriccurve/parametriccurve1,parametriccurve2 paramscatterplot + paramscatterplot_customsymbol #paramscatterplot_image parsedfunctionplot rgbimageplot diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox index 8d456ecf89..35b576738e 100644 --- a/doc/dox/examples_and_tutorials.dox +++ b/doc/dox/examples_and_tutorials.dox @@ -19,6 +19,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int \image html scatter_small.png \subpage JKQTPlotterscatter `JKQTPXYScatterGraph`
Iterator-Interface for JKQTDatastore + \image html scatter_customsymbol_small.png + \subpage JKQTPlotterscatterCustomSymbol + `JKQTPXYScatterGraph`
custom symbols JKQTPCharacterSymbol, JKQTPFilledCharacterSymbol, JKQTPRegisterCustomGraphSymbol()
Iterator-Interface for JKQTDatastore \image html speed_small.png \subpage JKQTPlotterSpeedTest `JKQTPXYLineGraph`
external `std::array` data, not owned by datastore
live-data, measure plotting speed
tipps to increas plotting speed @@ -49,9 +52,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int \image html impulsesplot_small.png \subpage JKQTPlotterImpulsePlots `JKQTPImpulsesVerticalGraph` and `JKQTPImpulsesHorizontalGraph`
C++-style QVector as plot data - \image html paramscatterplot_small.png - \subpage JKQTPlotterParamScatter + \image html paramscatterplot_small.png + \subpage JKQTPlotterParamScatter `JKQTPXYParametrizedScatterGraph`
C++-style QVector as plot data
modify scatter/points/line-graph properties by data + \image html paramscatterplot_customsymbol_small.png + \subpage JKQTPlotterparamscatterCustomSymbol + `JKQTPXYParametrizedScatterGraph`
custom and varying symbols using JKQTPRegisterCustomGraphSymbol()
iterator interface to `JKQTPDatastore` \image html paramscatterplot_image_small.png \subpage JKQTPlotterParamScatterImage `JKQTPXYParametrizedScatterGraph`
C++-style QVector as plot data
rectangular arrangement of scatters
generative computer graphics diff --git a/doc/images/JKQTPXYLineGraph.png b/doc/images/JKQTPXYLineGraph.png index 172f8b7e62..e374763b95 100644 Binary files a/doc/images/JKQTPXYLineGraph.png and b/doc/images/JKQTPXYLineGraph.png differ diff --git a/doc/images/JKQTPXYScatterErrorGraph.png b/doc/images/JKQTPXYScatterErrorGraph.png index 08e17cf16c..5ded3616dd 100644 Binary files a/doc/images/JKQTPXYScatterErrorGraph.png and b/doc/images/JKQTPXYScatterErrorGraph.png differ diff --git a/doc/images/JKQTPXYScatterErrorGraph_small.png b/doc/images/JKQTPXYScatterErrorGraph_small.png index 26256ee05d..913f0ec9e4 100644 Binary files a/doc/images/JKQTPXYScatterErrorGraph_small.png and b/doc/images/JKQTPXYScatterErrorGraph_small.png differ diff --git a/doc/images/JKQTPXYScatterGraph.png b/doc/images/JKQTPXYScatterGraph.png index f0923bd2f9..25d6d26f5d 100644 Binary files a/doc/images/JKQTPXYScatterGraph.png and b/doc/images/JKQTPXYScatterGraph.png differ diff --git a/doc/images/JKQTPXYScatterGraph_small.png b/doc/images/JKQTPXYScatterGraph_small.png index c3d79ce335..b2f9159b9c 100644 Binary files a/doc/images/JKQTPXYScatterGraph_small.png and b/doc/images/JKQTPXYScatterGraph_small.png differ diff --git a/doc/images/jkqtmathtext/jkqtmathtext_unicode.png b/doc/images/jkqtmathtext/jkqtmathtext_unicode.png index 8795d2d29b..936f5db9ee 100644 Binary files a/doc/images/jkqtmathtext/jkqtmathtext_unicode.png and b/doc/images/jkqtmathtext/jkqtmathtext_unicode.png differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4db5d2eb46..daf33071d6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -77,12 +77,14 @@ add_subdirectory(multiplot) add_subdirectory(parametriccurve) add_subdirectory(paramscatterplot) add_subdirectory(paramscatterplot_image) +add_subdirectory(paramscatterplot_customsymbol) add_subdirectory(parsedfunctionplot) add_subdirectory(rgbimageplot) add_subdirectory(rgbimageplot_cimg) add_subdirectory(rgbimageplot_opencv) add_subdirectory(rgbimageplot_qt) add_subdirectory(scatter) +add_subdirectory(scatter_customsymbol) add_subdirectory(speed) add_subdirectory(stackedbars) add_subdirectory(stepplots) diff --git a/examples/paramscatterplot_customsymbol/CMakeLists.txt b/examples/paramscatterplot_customsymbol/CMakeLists.txt new file mode 100644 index 0000000000..e8ecaafac9 --- /dev/null +++ b/examples/paramscatterplot_customsymbol/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.16) + +set(EXAMPLE_NAME paramscatterplot_customsymbol) +set(EXENAME jkqtptest_${EXAMPLE_NAME}) + +message( STATUS ".. Building Example ${EXAMPLE_NAME}" ) + + +# Set up source files +set(SOURCES paramscatterplot_customsymbol.cpp ) +set(HEADERS ) +set(RESOURCES ) +set(UIS ) + +add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS}) +target_link_libraries(${EXENAME} JKQTPExampleToolsLib) +target_include_directories(${EXENAME} PRIVATE ../../lib) +if(JKQtPlotter_BUILD_STATIC_LIBS) + target_link_libraries(${EXENAME} JKQTPlotterLib) + +elseif(JKQtPlotter_BUILD_SHARED_LIBS) + target_link_libraries(${EXENAME} JKQTPlotterSharedLib) +endif() + +# precomiled headers to speed up compilation +target_precompile_headers(${EXENAME} PRIVATE ../../lib/jkqtplotter/private/jkqtplotter_precomp.h) + + +# Installation +install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +#Installation of Qt DLLs on Windows +jkqtplotter_deployqt(${EXENAME}) diff --git a/examples/paramscatterplot_customsymbol/README.md b/examples/paramscatterplot_customsymbol/README.md new file mode 100644 index 0000000000..d284ce45e4 --- /dev/null +++ b/examples/paramscatterplot_customsymbol/README.md @@ -0,0 +1,69 @@ +# Example (JKQTPlotter): Parametrized Scatter-graph with custom symbols {#JKQTPlotterparamscatterCustomSymbol} + +This project (see `./examples/paramscatterplot_customsymbol/`) demonstrates using JKQTPlotter to draw a parametrized scatter graph (JKQTPXYParametrizedScatterGraph) with custom symbols. To demonstrate this, we create a plot with several symbols, connected by a line, where each symbol shows a pie-chart with varying fractions. + +The source code of the example can be found in [`paramscatterplot_customsymbol.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/paramscatterplot_customsymbol/paramscatterplot_customsymbol.cpp). + +First we create a plotter window and get a pointer to the internal datastore (for convenience). Then we add three new datacolumns and obtain back inserters. +```.cpp + JKQTPlotter plot; + JKQTPDatastore* ds=plot.getDatastore(); + + size_t columnX=ds->addColumn("x"); + auto colXInserter=ds->backInserter(columnX); + size_t columnY=ds->addColumn("y"); + auto colYInserter=ds->backInserter(columnY); + size_t columnS=ds->addColumn("sym"); + auto colSInserter=ds->backInserter(columnS); +``` +Now we define a functor that draws a pie chart with three segments with fractions `f1` (blue), `f2` (green) and `1.0-f1-f2` (yellow): +```.cpp + auto pieFunc=[](QPainter& p, double f1, double f2) { + double f3=1.0-f1-f2; + QRectF rec(-0.5,-0.5,1,1); + p.setPen(QPen(QColor("black"), p.pen().width(), Qt::SolidLine)); + p.setBrush(QBrush(QColor("blue"))); + p.drawPie(rec, 90, -f1*360*16); + p.setBrush(QBrush(QColor("green"))); + p.drawPie(rec, 90-f1*360*16, -f2*360*16); + p.setBrush(QBrush(QColor("yellow"))); + p.drawPie(rec, 90-(f1+f2)*360*16, -f3*360*16); + }; +``` +Now we create data for the plot, x and y follow a simple function and the symbols are encoded in a separated column, where for each datapoint, we register a new symbol using JKQTPRegisterCustomGraphSymbol(), which is drawn by a differently parametrized (f1,f2) functor pieFunc. +```.cpp + const int Ndata=5; + for (int i=0; isetXColumn(columnX); + graph1->setYColumn(columnY); + graph1->setSymbolSize(25); + graph1->setDrawLine(true); + graph1->setLineWidth(4); + graph1->setDrawLineInForeground(false); + graph1->setColor(QColor("black")); + graph1->setTitle(QObject::tr("pie scatter")); +``` +The symbol type is stored in columnS, note however how we have to give a custom JKQTPXYParametrizedScatterGraph::symbolColumnFunctor, because the default one maps the values in the column to the range `[0...JKQTPMaxSymbolID]` in a cycling fashion (using a mod operation), but here we want to use the `stored ID directly. +```.cpp + graph1->setSymbolColumn(columnS); + graph1->setSymbolColumnFunctor(std::bind([](double /*x*/, double /*y*/, double symbolcolumn)->JKQTPGraphSymbols { + return static_cast(floor(symbolcolumn)); + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + plot.addGraph(graph1); +``` +The result looks like this: + +![paramscatterplot_customsymbol](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/paramscatterplot_customsymbol.png) + + + diff --git a/examples/paramscatterplot_customsymbol/paramscatterplot_customsymbol.cpp b/examples/paramscatterplot_customsymbol/paramscatterplot_customsymbol.cpp new file mode 100644 index 0000000000..e37e752d4e --- /dev/null +++ b/examples/paramscatterplot_customsymbol/paramscatterplot_customsymbol.cpp @@ -0,0 +1,96 @@ +/** \example scatter_customsymbol.cpp + * Usage of JKQTPScatterGraph with custom symbols + * + * \ref JKQTPlotterscatterCustomSymbol + */ + +#include "jkqtpexampleapplication.h" +#include +#include "jkqtplotter/jkqtplotter.h" +#include "jkqtplotter/graphs/jkqtpscatter.h" +#include "jkqtpexampleapplication.h" +#include + +int main(int argc, char* argv[]) +{ + + JKQTPAppSettingController highDPIController(argc,argv); + JKQTPExampleApplication 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. add three columns to the JKQTPDatastore and obtain back-inserter iterators for these + size_t columnX=ds->addColumn("x"); + auto colXInserter=ds->backInserter(columnX); + size_t columnY=ds->addColumn("y"); + auto colYInserter=ds->backInserter(columnY); + size_t columnS=ds->addColumn("sym"); + auto colSInserter=ds->backInserter(columnS); + + // 3. now we define a functor that draws a pie chart with three segments with fractions + // f1 (blue), f2 (green) and 1-f1-f2 (yellow) + auto pieFunc=[](QPainter& p, double f1, double f2) { + double f3=1.0-f1-f2; + QRectF rec(-0.5,-0.5,1,1); + p.setPen(QPen(QColor("black"), p.pen().width(), Qt::SolidLine)); + p.setBrush(QBrush(QColor("blue"))); + p.drawPie(rec, 90, -f1*360*16); + p.setBrush(QBrush(QColor("green"))); + p.drawPie(rec, 90-f1*360*16, -f2*360*16); + p.setBrush(QBrush(QColor("yellow"))); + p.drawPie(rec, 90-(f1+f2)*360*16, -f3*360*16); + }; + // 4. now we create data for the plot, x and y follow a simple function + // and the symbols are encoded in a separated column, where for each datapoint, we + // register a new symbol using JKQTPRegisterCustomGraphSymbol(), which is drawn by + // a differently parametrized (f1,f2) functor pieFunc. + const int Ndata=5; + for (int i=0; isetXColumn(columnX); + graph1->setYColumn(columnY); + graph1->setSymbolSize(25); + graph1->setDrawLine(true); + graph1->setLineWidth(4); + graph1->setDrawLineInForeground(false); + graph1->setColor(QColor("black")); + graph1->setTitle(QObject::tr("pie scatter")); + // the symbol type is stored in columnS, note however how we have to give a + // custom JKQTPXYParametrizedScatterGraph::symbolColumnFunctor, because the + // default one maps the values in the column to the range [0...JKQTPMaxSymbolID] + // in a cycling fashion (using a mod operation), but here we want to use the + // stored ID directly. + graph1->setSymbolColumn(columnS); + graph1->setSymbolColumnFunctor(std::bind([](double /*x*/, double /*y*/, double symbolcolumn)->JKQTPGraphSymbols { + return static_cast(floor(symbolcolumn)); + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + plot.addGraph(graph1); + + + // 6. autoscale the plot so the graph is contained + plot.setXY(-0.2,1.2,-0.4,2.2); + + // show plotter and make it a decent size + plot.getXAxis()->setShowZeroAxis(false); + plot.getYAxis()->setShowZeroAxis(false); + plot.setGrid(false); + plot.getPlotter()->setKeyPosition(JKQTPKeyInsideTopLeft); + plot.getPlotter()->setPlotLabel(QObject::tr("Custom Parametrized Scatter Symbols Example")); + plot.show(); + plot.resize(500/plot.devicePixelRatioF(),400/plot.devicePixelRatioF()); + + + return app.exec(); +} diff --git a/examples/scatter_customsymbol/CMakeLists.txt b/examples/scatter_customsymbol/CMakeLists.txt new file mode 100644 index 0000000000..1633ce6982 --- /dev/null +++ b/examples/scatter_customsymbol/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.16) + +set(EXAMPLE_NAME scatter_customsymbol) +set(EXENAME jkqtptest_${EXAMPLE_NAME}) + +message( STATUS ".. Building Example ${EXAMPLE_NAME}" ) + + +# Set up source files +set(SOURCES scatter_customsymbol.cpp ) +set(HEADERS ) +set(RESOURCES ) +set(UIS ) + +add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS}) +target_link_libraries(${EXENAME} JKQTPExampleToolsLib) +target_include_directories(${EXENAME} PRIVATE ../../lib) +if(JKQtPlotter_BUILD_STATIC_LIBS) + target_link_libraries(${EXENAME} JKQTPlotterLib) + +elseif(JKQtPlotter_BUILD_SHARED_LIBS) + target_link_libraries(${EXENAME} JKQTPlotterSharedLib) +endif() + +# precomiled headers to speed up compilation +target_precompile_headers(${EXENAME} PRIVATE ../../lib/jkqtplotter/private/jkqtplotter_precomp.h) + + +# Installation +install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +#Installation of Qt DLLs on Windows +jkqtplotter_deployqt(${EXENAME}) diff --git a/examples/scatter_customsymbol/README.md b/examples/scatter_customsymbol/README.md new file mode 100644 index 0000000000..2ae9c7d3b0 --- /dev/null +++ b/examples/scatter_customsymbol/README.md @@ -0,0 +1,113 @@ +# Example (JKQTPlotter): Scatter-graph with custom symbols {#JKQTPlotterscatterCustomSymbol} + +This project (see `./examples/scatter_customsymbol/`) demonstrates using JKQTPlotter to draw a scatter graph (JKQTPXYScatterGraph) with custom symbols. + +The source code of the example can be found in [`jkqtplotter_scatter.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/scatter_customsymbol/scatter_customsymbol.cpp). + +First we create a plotter window and get a pointer to the internal datastore (for convenience): +```.cpp + JKQTPlotter plot; + JKQTPDatastore* ds=plot.getDatastore(); +``` +Now we add several columns to the JKQTPDatastore and obtain back-inserter iterators for these: +```.cpp + size_t columnX=ds->addColumn("x"); + auto colXInserter=ds->backInserter(columnX); + size_t columnY1=ds->addColumn("y1"); + auto colY1Inserter=ds->backInserter(columnY1); + size_t columnY2=ds->addColumn("y2"); + auto colY2Inserter=ds->backInserter(columnY2); + size_t columnY3=ds->addColumn("y3"); + auto colY3Inserter=ds->backInserter(columnY3); + size_t columnY4=ds->addColumn("y4"); + auto colY4Inserter=ds->backInserter(columnY4); +``` +... and fill the columns with data +```.cpp + const int Ndata=5; + for (int i=0; isetXColumn(columnX); + graph3->setYColumn(columnY3); + graph3->setSymbolType(JKQTPCharacterSymbol+QChar(0x2660).unicode()); + graph3->setSymbolColor(QColor("darkblue")); + graph3->setSymbolSize(15); + graph3->setTitle(QObject::tr("spades")); + plot.addGraph(graph3); + + JKQTPXYScatterGraph* graph4=new JKQTPXYScatterGraph(&plot); + graph4->setXColumn(columnX); + graph4->setYColumn(columnY4); + graph4->setSymbolType(JKQTPFilledCharacterSymbol+QChar(0x2665).unicode()); + graph4->setSymbolSize(20); + graph4->setSymbolColor(QColor("black")); + graph4->setSymbolFillColor(QColor("red")); + graph4->setSymbolLineWidth(0.5); + graph4->setTitle(QObject::tr("hearts")); + plot.addGraph(graph4); +``` + +The more advanced graphs `graph1` and `graph2` use `JKQTPRegisterCustomGraphSymbol()` to register functors that draw user-specific symbols: +```.cpp + JKQTPCustomGraphSymbolFunctor f=[](QPainter& p) { + p.setBrush(Qt::NoBrush); // ensure that circles are not drawn filled + p.drawEllipse(QPointF(-0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0); + p.drawEllipse(QPointF(0, -0.33/4.0), 0.33/2.0, 0.33/2.0); + p.drawEllipse(QPointF(0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0); + p.drawEllipse(QPointF(-0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0); + p.drawEllipse(QPointF(0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0); + }; + JKQTPGraphSymbols customsymbol_olympicrings=JKQTPRegisterCustomGraphSymbol(f); + JKQTPXYScatterGraph* graph1=new JKQTPXYScatterGraph(&plot); + graph1->setXColumn(columnX); + graph1->setYColumn(columnY1); + graph1->setSymbolType(customsymbol_olympicrings); + graph1->setSymbolSize(30); + graph1->setTitle(QObject::tr("olympics")); + plot.addGraph(graph1); + + + JKQTPGraphSymbols customsymbol_coloredolympicrings=JKQTPRegisterCustomGraphSymbol( + [](QPainter& p) { + p.setBrush(Qt::NoBrush); // ensure that circles are not drawn filled + const double w=p.pen().widthF(); + p.setPen(QPen(QColor("red"), w)); + p.drawEllipse(QPointF(-0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0); + p.setPen(QPen(QColor("black"), w)); + p.drawEllipse(QPointF(0, -0.33/4.0), 0.33/2.0, 0.33/2.0); + p.setPen(QPen(QColor("gold"), w)); + p.drawEllipse(QPointF(0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0); + p.setPen(QPen(QColor("darkgreen"), w)); + p.drawEllipse(QPointF(-0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0); + p.setPen(QPen(QColor("darkblue"), w)); + p.drawEllipse(QPointF(0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0); + }); + JKQTPXYScatterGraph* graph2=new JKQTPXYScatterGraph(&plot); + graph2->setXColumn(columnX); + graph2->setYColumn(columnY2); + graph2->setSymbolType(customsymbol_coloredolympicrings); + graph2->setSymbolSize(30); + graph2->setTitle(QObject::tr("colored olympics")); + plot.addGraph(graph2); +``` +Bothe variant show the olympic rings. `graph1` uses the (cycling) default graph color and `graph2` draws with user-defined colors. + +The result looks like this: + +![scatter_customsymbol](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/scatter_customsymbol.png) + + + diff --git a/examples/scatter_customsymbol/scatter_customsymbol.cpp b/examples/scatter_customsymbol/scatter_customsymbol.cpp new file mode 100644 index 0000000000..0488494b60 --- /dev/null +++ b/examples/scatter_customsymbol/scatter_customsymbol.cpp @@ -0,0 +1,127 @@ +/** \example scatter_customsymbol.cpp + * Usage of JKQTPScatterGraph with custom symbols + * + * \ref JKQTPlotterscatterCustomSymbol + */ + +#include "jkqtpexampleapplication.h" +#include +#include "jkqtplotter/jkqtplotter.h" +#include "jkqtplotter/graphs/jkqtpscatter.h" +#include "jkqtpexampleapplication.h" +#include + +int main(int argc, char* argv[]) +{ + + JKQTPAppSettingController highDPIController(argc,argv); + JKQTPExampleApplication 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. add two columns to the JKQTPDatastore and obtain back-inserter iterators for these + size_t columnX=ds->addColumn("x"); + auto colXInserter=ds->backInserter(columnX); + size_t columnY1=ds->addColumn("y1"); + auto colY1Inserter=ds->backInserter(columnY1); + size_t columnY2=ds->addColumn("y2"); + auto colY2Inserter=ds->backInserter(columnY2); + size_t columnY3=ds->addColumn("y3"); + auto colY3Inserter=ds->backInserter(columnY3); + size_t columnY4=ds->addColumn("y4"); + auto colY4Inserter=ds->backInserter(columnY4); + + + // 3. now we create data for a simple plot (a sine curve with random noise) + const int Ndata=5; + for (int i=0; isetXColumn(columnX); + graph1->setYColumn(columnY1); + graph1->setSymbolType(customsymbol_olympicrings); + graph1->setSymbolSize(30); + graph1->setTitle(QObject::tr("olympics")); + plot.addGraph(graph1); + + JKQTPXYScatterGraph* graph2=new JKQTPXYScatterGraph(&plot); + graph2->setXColumn(columnX); + graph2->setYColumn(columnY2); + graph2->setSymbolType(customsymbol_coloredolympicrings); + graph2->setSymbolSize(30); + graph2->setTitle(QObject::tr("colored olympics")); + plot.addGraph(graph2); + + JKQTPXYScatterGraph* graph3=new JKQTPXYScatterGraph(&plot); + graph3->setXColumn(columnX); + graph3->setYColumn(columnY3); + graph3->setSymbolType(JKQTPCharacterSymbol+QChar(0x2660).unicode()); + graph3->setSymbolColor(QColor("darkblue")); + graph3->setSymbolSize(15); + graph3->setTitle(QObject::tr("spades")); + plot.addGraph(graph3); + + JKQTPXYScatterGraph* graph4=new JKQTPXYScatterGraph(&plot); + graph4->setXColumn(columnX); + graph4->setYColumn(columnY4); + graph4->setSymbolType(JKQTPFilledCharacterSymbol+QChar(0x2665).unicode()); + graph4->setSymbolSize(20); + graph4->setSymbolColor(QColor("black")); + graph4->setSymbolFillColor(QColor("red")); + graph4->setSymbolLineWidth(0.5); + graph4->setTitle(QObject::tr("hearts")); + plot.addGraph(graph4); + + // 6. autoscale the plot so the graph is contained + plot.setXY(-0.1,1.1,-1, 6); + + // show plotter and make it a decent size + plot.getXAxis()->setShowZeroAxis(false); + plot.getYAxis()->setShowZeroAxis(false); + plot.setGrid(false); + plot.getPlotter()->setKeyPosition(JKQTPKeyInsideTopLeft); + plot.getPlotter()->setPlotLabel(QObject::tr("Custom Scatter Symbols Example")); + plot.show(); + plot.resize(500/plot.devicePixelRatioF(),500/plot.devicePixelRatioF()); + + return app.exec(); +} diff --git a/screenshots/boxplot.png b/screenshots/boxplot.png index 343019fe38..ef1269c6d2 100644 Binary files a/screenshots/boxplot.png and b/screenshots/boxplot.png differ diff --git a/screenshots/boxplot_small.png b/screenshots/boxplot_small.png index cebee372b9..e0d40a7407 100644 Binary files a/screenshots/boxplot_small.png and b/screenshots/boxplot_small.png differ diff --git a/screenshots/dateaxes_timeaxis.png b/screenshots/dateaxes_timeaxis.png index 5eedcc5407..218ea12092 100644 Binary files a/screenshots/dateaxes_timeaxis.png and b/screenshots/dateaxes_timeaxis.png differ diff --git a/screenshots/dateaxes_timeaxis_small.png b/screenshots/dateaxes_timeaxis_small.png index f9294c8efb..30c52ff4c6 100644 Binary files a/screenshots/dateaxes_timeaxis_small.png and b/screenshots/dateaxes_timeaxis_small.png differ diff --git a/screenshots/errorbarstyles.png b/screenshots/errorbarstyles.png index 099a918ead..99c20a2ae6 100644 Binary files a/screenshots/errorbarstyles.png and b/screenshots/errorbarstyles.png differ diff --git a/screenshots/errorbarstyles_small.png b/screenshots/errorbarstyles_small.png index d34b5d92b0..4bd977703a 100644 Binary files a/screenshots/errorbarstyles_small.png and b/screenshots/errorbarstyles_small.png differ diff --git a/screenshots/geometric.png b/screenshots/geometric.png index 7c514b268b..f982a39134 100644 Binary files a/screenshots/geometric.png and b/screenshots/geometric.png differ diff --git a/screenshots/geometric_small.png b/screenshots/geometric_small.png index 8a25435e53..eb50a089be 100644 Binary files a/screenshots/geometric_small.png and b/screenshots/geometric_small.png differ diff --git a/screenshots/imageplot_userpal_program.png b/screenshots/imageplot_userpal_program.png index 05829af909..6a3bcd14e4 100644 Binary files a/screenshots/imageplot_userpal_program.png and b/screenshots/imageplot_userpal_program.png differ diff --git a/screenshots/imageplot_userpal_program_small.png b/screenshots/imageplot_userpal_program_small.png index 06f28886be..24cf2c20e3 100644 Binary files a/screenshots/imageplot_userpal_program_small.png and b/screenshots/imageplot_userpal_program_small.png differ diff --git a/screenshots/multiplot.png b/screenshots/multiplot.png index bfb90e4a88..215106c7dd 100644 Binary files a/screenshots/multiplot.png and b/screenshots/multiplot.png differ diff --git a/screenshots/multiplot_controlwindow.png b/screenshots/multiplot_controlwindow.png index 5fe791c503..bf548904a3 100644 Binary files a/screenshots/multiplot_controlwindow.png and b/screenshots/multiplot_controlwindow.png differ diff --git a/screenshots/multiplot_controlwindow_small.png b/screenshots/multiplot_controlwindow_small.png index 8e87106b18..b755e78628 100644 Binary files a/screenshots/multiplot_controlwindow_small.png and b/screenshots/multiplot_controlwindow_small.png differ diff --git a/screenshots/paramscatterplot.png b/screenshots/paramscatterplot.png index d78476f44c..df9c970444 100644 Binary files a/screenshots/paramscatterplot.png and b/screenshots/paramscatterplot.png differ diff --git a/screenshots/paramscatterplot_customsymbol.png b/screenshots/paramscatterplot_customsymbol.png new file mode 100644 index 0000000000..1fe7d55499 Binary files /dev/null and b/screenshots/paramscatterplot_customsymbol.png differ diff --git a/screenshots/paramscatterplot_customsymbol_small.png b/screenshots/paramscatterplot_customsymbol_small.png new file mode 100644 index 0000000000..f08e5ce0f1 Binary files /dev/null and b/screenshots/paramscatterplot_customsymbol_small.png differ diff --git a/screenshots/paramscatterplot_small.png b/screenshots/paramscatterplot_small.png index 6c8b878d18..5432617f05 100644 Binary files a/screenshots/paramscatterplot_small.png and b/screenshots/paramscatterplot_small.png differ diff --git a/screenshots/scatter.png b/screenshots/scatter.png index bf54f5d841..8fd90630ed 100644 Binary files a/screenshots/scatter.png and b/screenshots/scatter.png differ diff --git a/screenshots/scatter_customsymbol.png b/screenshots/scatter_customsymbol.png new file mode 100644 index 0000000000..05f39d8c28 Binary files /dev/null and b/screenshots/scatter_customsymbol.png differ diff --git a/screenshots/scatter_customsymbol_small.png b/screenshots/scatter_customsymbol_small.png new file mode 100644 index 0000000000..2dfa5594d7 Binary files /dev/null and b/screenshots/scatter_customsymbol_small.png differ diff --git a/screenshots/scatter_error.png b/screenshots/scatter_error.png index 0925e26973..2272c62c7c 100644 Binary files a/screenshots/scatter_error.png and b/screenshots/scatter_error.png differ diff --git a/screenshots/scatter_error_small.png b/screenshots/scatter_error_small.png index 26256ee05d..913f0ec9e4 100644 Binary files a/screenshots/scatter_error_small.png and b/screenshots/scatter_error_small.png differ diff --git a/screenshots/scatter_small.png b/screenshots/scatter_small.png index c3d79ce335..b2f9159b9c 100644 Binary files a/screenshots/scatter_small.png and b/screenshots/scatter_small.png differ diff --git a/screenshots/stepplots.png b/screenshots/stepplots.png index e1b466345a..479a98f74c 100644 Binary files a/screenshots/stepplots.png and b/screenshots/stepplots.png differ diff --git a/screenshots/stepplots_small.png b/screenshots/stepplots_small.png index 61c4b50e77..59a4e960fd 100644 Binary files a/screenshots/stepplots_small.png and b/screenshots/stepplots_small.png differ diff --git a/screenshots/test_distributionplot.png b/screenshots/test_distributionplot.png index bc2197fa89..50233e8940 100644 Binary files a/screenshots/test_distributionplot.png and b/screenshots/test_distributionplot.png differ diff --git a/screenshots/test_distributionplot_small.png b/screenshots/test_distributionplot_small.png index e28a55a352..e4be367af3 100644 Binary files a/screenshots/test_distributionplot_small.png and b/screenshots/test_distributionplot_small.png differ diff --git a/screenshots/violinplot_hor.png b/screenshots/violinplot_hor.png index 7c0447a78f..0a38b0bfdf 100644 Binary files a/screenshots/violinplot_hor.png and b/screenshots/violinplot_hor.png differ diff --git a/screenshots/violinplot_vert.png b/screenshots/violinplot_vert.png index c7c4384adf..1474da8e2e 100644 Binary files a/screenshots/violinplot_vert.png and b/screenshots/violinplot_vert.png differ diff --git a/screenshots/violinplot_vert_small.png b/screenshots/violinplot_vert_small.png index b8adc3fafc..0c11a2abcd 100644 Binary files a/screenshots/violinplot_vert_small.png and b/screenshots/violinplot_vert_small.png differ