mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 10:01:38 +08:00
NEW: added scatter graph JKQTPXYScatterGraph and JKQTPXYScatterErrorGraph
This commit is contained in:
parent
02fbabff5c
commit
b156fc7e40
@ -283,6 +283,9 @@ This group assembles graphs that show their data with symbols and optionally wit
|
|||||||
<tr>
|
<tr>
|
||||||
<td>\image html beeswarmplot_small.png
|
<td>\image html beeswarmplot_small.png
|
||||||
<td> JKQTPSingleColumnSymbolsGraph
|
<td> JKQTPSingleColumnSymbolsGraph
|
||||||
|
<tr>
|
||||||
|
<td>\image html scatter_small.png
|
||||||
|
<td> JKQTPXYScatterGraph, JKQTPXYScatterErrorGraph
|
||||||
<tr>
|
<tr>
|
||||||
<td>\image html symbols_and_styles_small.png
|
<td>\image html symbols_and_styles_small.png
|
||||||
<td> JKQTPXYLineGraph, JKQTPXYLineErrorGraph
|
<td> JKQTPXYLineGraph, JKQTPXYLineErrorGraph
|
||||||
|
@ -37,6 +37,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
|||||||
<li>NEW: improved plotting speed for scatter-graphs by not calling draw functions for symbols outside the plot window (e.g. in JKQTPXYLineGraph)</li>
|
<li>NEW: improved plotting speed for scatter-graphs by not calling draw functions for symbols outside the plot window (e.g. in JKQTPXYLineGraph)</li>
|
||||||
<li>NEW: added JKQTBasePlotter::grabPixelImage() and JKQTPlotter::grabPixelImage(), which grab the plotter into a QImage</li>
|
<li>NEW: added JKQTBasePlotter::grabPixelImage() and JKQTPlotter::grabPixelImage(), which grab the plotter into a QImage</li>
|
||||||
<li>NEW: added option to not display the preview dialog to JKQTBasePlotter::copyPixelImage() and JKQTPlotter::copyPixelImage()</li>
|
<li>NEW: added option to not display the preview dialog to JKQTBasePlotter::copyPixelImage() and JKQTPlotter::copyPixelImage()</li>
|
||||||
|
<li>NEW: added simple scatter plot JKQTPXYScatterGraph</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
|
|
||||||
<li>JKQTMathText:<ul>
|
<li>JKQTMathText:<ul>
|
||||||
|
@ -48,6 +48,211 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPXYScatterGraph::JKQTPXYScatterGraph(JKQTPlotter* parent):
|
||||||
|
JKQTPXYScatterGraph(parent->getPlotter())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPXYScatterGraph::JKQTPXYScatterGraph(JKQTBasePlotter* parent):
|
||||||
|
JKQTPXYGraph(parent)
|
||||||
|
{
|
||||||
|
sortData=JKQTPXYGraph::Unsorted;
|
||||||
|
|
||||||
|
initSymbolStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPXYScatterGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaaot("JKQTPXYScatterGraph::draw");
|
||||||
|
#endif
|
||||||
|
if (parent==nullptr) return;
|
||||||
|
const JKQTPDatastore* datastore=parent->getDatastore();
|
||||||
|
if (datastore==nullptr) return;
|
||||||
|
|
||||||
|
//qDebug()<<"JKQTPXYScatterGraph::draw();";
|
||||||
|
|
||||||
|
drawErrorsBefore(painter);
|
||||||
|
{
|
||||||
|
//qDebug()<<"JKQTPXYScatterGraph::draw(): "<<1;
|
||||||
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
|
//qDebug()<<"JKQTPXYScatterGraph::draw(): "<<2;
|
||||||
|
|
||||||
|
const auto symType=getSymbolType();
|
||||||
|
const double xmin=transformX(parent->getXAxis()->getMin());
|
||||||
|
const double xmax=transformX(parent->getXAxis()->getMax());
|
||||||
|
const double ymin=transformY(parent->getYAxis()->getMin());
|
||||||
|
const double ymax=transformY(parent->getYAxis()->getMax());
|
||||||
|
const double symbolSize=parent->pt2px(painter, getSymbolSize());
|
||||||
|
const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize);
|
||||||
|
const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins;
|
||||||
|
|
||||||
|
|
||||||
|
int imax=0;
|
||||||
|
int imin=0;
|
||||||
|
if (getIndexRange(imin, imax)) {
|
||||||
|
for (int iii=imin; iii<imax; iii++) {
|
||||||
|
const int i=qBound(imin, getDataIndex(iii), imax);
|
||||||
|
const double xv=datastore->get(static_cast<size_t>(xColumn),static_cast<size_t>(i));
|
||||||
|
const double yv=datastore->get(static_cast<size_t>(yColumn),static_cast<size_t>(i));
|
||||||
|
const double x=transformX(xv);
|
||||||
|
const double y=transformY(yv);
|
||||||
|
//qDebug()<<"JKQTPXYScatterGraph::draw(): (xv, yv) = ( "<<xv<<", "<<yv<<" )";
|
||||||
|
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(yv) && JKQTPIsOKFloat(x) && JKQTPIsOKFloat(y)) {
|
||||||
|
|
||||||
|
//if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol) {
|
||||||
|
//JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle, parent->pt2px(painter, symbolSize*1.5), parent->pt2px(painter, symbolWidth*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color());
|
||||||
|
//}
|
||||||
|
if ((!parent->getXAxis()->isLogAxis() || xv>0.0) && (!parent->getYAxis()->isLogAxis() || yv>0.0) ) {
|
||||||
|
if (symType!=JKQTPNoSymbol && cliprect.contains(x,y)) plotStyledSymbol(parent, painter, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//qDebug()<<"JKQTPXYScatterGraph::draw(): "<<7;
|
||||||
|
drawErrorsAfter(painter);
|
||||||
|
//qDebug()<<"JKQTPXYScatterGraph::draw() ... done";
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPXYScatterGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
|
||||||
|
const double minSize=qMin(rect.width(), rect.height());
|
||||||
|
const double maxSize=qMax(rect.width(), rect.height());
|
||||||
|
double symbolSize=parent->pt2px(painter, this->getSymbolSize());
|
||||||
|
if (symbolSize>minSize*0.9) symbolSize=minSize*0.9;
|
||||||
|
double symbolWidth=parent->pt2px(painter, this->getSymbolLineWidth()*parent->getLineWidthMultiplier());
|
||||||
|
if (symbolWidth>0.3*symbolSize) symbolWidth=0.3*symbolSize;
|
||||||
|
|
||||||
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
|
double y=rect.top()+rect.height()/2.0;
|
||||||
|
JKQTPPlotSymbol(painter, rect.left()+rect.width()/2.0, rect.top()+rect.height()/2.0, getSymbolType(), symbolSize, symbolWidth, getKeyLabelColor(), getSymbolFillColor());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor JKQTPXYScatterGraph::getKeyLabelColor() const {
|
||||||
|
return getSymbolColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPXYScatterGraph::setColor(QColor c)
|
||||||
|
{
|
||||||
|
setSymbolColor(c);
|
||||||
|
setSymbolFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.defaultGraphStyle.fillColorDerivationMode, c));
|
||||||
|
c.setAlphaF(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPXYScatterErrorGraph::JKQTPXYScatterErrorGraph(JKQTBasePlotter *parent):
|
||||||
|
JKQTPXYScatterGraph(parent)
|
||||||
|
{
|
||||||
|
setErrorColorFromGraphColor(getSymbolColor());
|
||||||
|
initErrorStyle(parent, parentPlotStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPXYScatterErrorGraph::JKQTPXYScatterErrorGraph(JKQTPlotter *parent):
|
||||||
|
JKQTPXYScatterErrorGraph(parent->getPlotter())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPXYScatterErrorGraph::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero) {
|
||||||
|
if (xErrorColumn<0 || xErrorStyle==JKQTPNoError) {
|
||||||
|
return JKQTPXYScatterGraph::getXMinMax(minx, maxx, smallestGreaterZero);
|
||||||
|
} else {
|
||||||
|
bool start=true;
|
||||||
|
minx=0;
|
||||||
|
maxx=0;
|
||||||
|
smallestGreaterZero=0;
|
||||||
|
|
||||||
|
if (parent==nullptr) return false;
|
||||||
|
|
||||||
|
const JKQTPDatastore* datastore=parent->getDatastore();
|
||||||
|
int imax=0;
|
||||||
|
int imin=0;
|
||||||
|
if (getIndexRange(imin, imax)) {
|
||||||
|
for (int i=imin; i<imax; i++) {
|
||||||
|
double xv=datastore->get(static_cast<size_t>(xColumn),static_cast<size_t>(i))+getXErrorU(i, datastore);
|
||||||
|
if (JKQTPIsOKFloat(xv)) {
|
||||||
|
if (start || xv>maxx) maxx=xv;
|
||||||
|
if (start || xv<minx) minx=xv;
|
||||||
|
const double xvsgz=xv; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
start=false;
|
||||||
|
}
|
||||||
|
xv=datastore->get(static_cast<size_t>(xColumn),static_cast<size_t>(i))-getXErrorL(i, datastore);
|
||||||
|
if (JKQTPIsOKFloat(xv)) {
|
||||||
|
if (start || xv>maxx) maxx=xv;
|
||||||
|
if (start || xv<minx) minx=xv;
|
||||||
|
const double xvsgz=xv; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
start=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPXYScatterErrorGraph::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero) {
|
||||||
|
if (yErrorColumn<0 || yErrorStyle==JKQTPNoError) {
|
||||||
|
return JKQTPXYScatterGraph::getYMinMax(miny, maxy, smallestGreaterZero);
|
||||||
|
} else {
|
||||||
|
bool start=true;
|
||||||
|
miny=0;
|
||||||
|
maxy=0;
|
||||||
|
smallestGreaterZero=0;
|
||||||
|
|
||||||
|
if (parent==nullptr) return false;
|
||||||
|
|
||||||
|
const JKQTPDatastore* datastore=parent->getDatastore();
|
||||||
|
int imax=0;
|
||||||
|
int imin=0;
|
||||||
|
if (getIndexRange(imin, imax)) {
|
||||||
|
for (int i=imin; i<imax; i++) {
|
||||||
|
double yv=datastore->get(static_cast<size_t>(yColumn),static_cast<size_t>(i))+getYErrorU(i, datastore);
|
||||||
|
if (JKQTPIsOKFloat(yv)) {
|
||||||
|
if (start || yv>maxy) maxy=yv;
|
||||||
|
if (start || yv<miny) miny=yv;
|
||||||
|
const double xvsgz=yv; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
start=false;
|
||||||
|
}
|
||||||
|
yv=datastore->get(static_cast<size_t>(yColumn),static_cast<size_t>(i))-getYErrorL(i, datastore);
|
||||||
|
if (JKQTPIsOKFloat(yv)) {
|
||||||
|
if (start || yv>maxy) maxy=yv;
|
||||||
|
if (start || yv<miny) miny=yv;
|
||||||
|
const double xvsgz=yv; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
start=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPXYScatterErrorGraph::usesColumn(int c) const
|
||||||
|
{
|
||||||
|
return JKQTPXYScatterGraph::usesColumn(c)||JKQTPXYGraphErrors::errorUsesColumn(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPXYScatterErrorGraph::drawErrorsBefore(JKQTPEnhancedPainter &painter)
|
||||||
|
{
|
||||||
|
intSortData();
|
||||||
|
if (sortData==JKQTPXYGraph::Unsorted) plotErrorIndicators(painter, parent, this, xColumn, yColumn);
|
||||||
|
else plotErrorIndicators(painter, parent, this, xColumn, yColumn, 0, 0, &sortedIndices);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,9 +45,88 @@ class JKQTPDatastore;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief This implements xy scatter plots. This also alows to draw symbols at the data points.
|
||||||
|
\ingroup jkqtplotter_linesymbolgraphs_simple
|
||||||
|
|
||||||
|
\image html plot_scatterplots.png
|
||||||
|
|
||||||
|
\note This classes can (and does by default) apply a line-compression strategy that improves plotting speed
|
||||||
|
but reduces accuracy a bit. See JKQTPGraphLinesCompressionMixin for details.
|
||||||
|
|
||||||
|
\see JKQTPXYScatterErrorGraph for a version with error indicators and JKQTPXYParametrizedScatterGraph for a more feature-rich version
|
||||||
|
that allows to also change the color/size of the symbols from data
|
||||||
|
*/
|
||||||
|
class JKQTPLOTTER_LIB_EXPORT JKQTPXYScatterGraph: public JKQTPXYGraph, public JKQTPGraphSymbolStyleMixin {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/** \brief class constructor */
|
||||||
|
explicit JKQTPXYScatterGraph(JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXYScatterGraph(JKQTPlotter* parent);
|
||||||
|
|
||||||
|
/** \brief plots the graph to the plotter object specified as parent */
|
||||||
|
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
||||||
|
/** \brief plots a key marker inside the specified rectangle \a rect */
|
||||||
|
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override;
|
||||||
|
/** \brief returns the color to be used for the key label */
|
||||||
|
virtual QColor getKeyLabelColor() const override;
|
||||||
|
/** \brief set color of line and symbol */
|
||||||
|
void setColor(QColor c);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
/*! \brief This implements xy scatter plots (like JKQTPXYLineGraph), but the color and size of the symbols may be taken from a column.
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief This implements xy scatter plots with x and y error indicators.
|
||||||
|
\ingroup jkqtplotter_linesymbolgraphs_simple
|
||||||
|
|
||||||
|
\image html plot_errorbarscatterlots.png
|
||||||
|
|
||||||
|
\see JKQTPXYScatterGraph, JKQTPXYGraphErrors
|
||||||
|
*/
|
||||||
|
class JKQTPLOTTER_LIB_EXPORT JKQTPXYScatterErrorGraph: public JKQTPXYScatterGraph, public JKQTPXYGraphErrors {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXYScatterErrorGraph(JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXYScatterErrorGraph(JKQTPlotter* parent);
|
||||||
|
|
||||||
|
/** \brief get the maximum and minimum x-value of the graph
|
||||||
|
*
|
||||||
|
* The result is given in the two parameters which are call-by-reference parameters!
|
||||||
|
*/
|
||||||
|
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
||||||
|
/** \brief get the maximum and minimum y-value of the graph
|
||||||
|
*
|
||||||
|
* The result is given in the two parameters which are call-by-reference parameters!
|
||||||
|
*/
|
||||||
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||||
|
/** \copydoc JKQTPGraph::usesColumn() */
|
||||||
|
virtual bool usesColumn(int c) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \brief this function is used to plot error inidcators before plotting the graphs. */
|
||||||
|
virtual void drawErrorsBefore(JKQTPEnhancedPainter& painter) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief This implements xy scatter plots (like JKQTPXYScatterGraph), but the color and size of the symbols may be taken from a column.
|
||||||
\ingroup jkqtplotter_linesymbolgraphs_param
|
\ingroup jkqtplotter_linesymbolgraphs_param
|
||||||
|
|
||||||
set the properties sizeColumn and/or colorColumn to change the size and/or color of the symbols according to the values in the column.
|
set the properties sizeColumn and/or colorColumn to change the size and/or color of the symbols according to the values in the column.
|
||||||
@ -55,7 +134,7 @@ class JKQTPDatastore;
|
|||||||
\image html paramscatterplot.png "Different Styles of Parametrized Scatter/Line Graphs"
|
\image html paramscatterplot.png "Different Styles of Parametrized Scatter/Line Graphs"
|
||||||
|
|
||||||
\note This classes is meant for cases where you want to change the color/size/... of single symbols, in dependence
|
\note This classes is meant for cases where you want to change the color/size/... of single symbols, in dependence
|
||||||
of data. If you are looking for a simple scatter-plot without data-dependent properties, use JKQTPXYLineGraph
|
of data. If you are looking for a simple scatter-plot without data-dependent properties, use JKQTPXYScatterGraph
|
||||||
instead, which is faster.
|
instead, which is faster.
|
||||||
|
|
||||||
\note For the size, line width and symbol type columns, you can also set a functor, which converts the column value (optionally based
|
\note For the size, line width and symbol type columns, you can also set a functor, which converts the column value (optionally based
|
||||||
@ -331,7 +410,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYParametrizedScatterGraph: public JKQTPXYGrap
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief This implements xy scatter plots (like JKQTPXYLineGraph), but the color and size of the symbols may be taken from a column. with errorbars
|
/*! \brief This implements xy scatter plots (like JKQTPXYScatterGraph), but the color and size of the symbols may be taken from a column. with errorbars
|
||||||
\ingroup jkqtplotter_linesymbolgraphs_param
|
\ingroup jkqtplotter_linesymbolgraphs_param
|
||||||
|
|
||||||
set the properties sizeColumn and/or colorColumn to change the size and/or color of the symbols according to the values in the column.
|
set the properties sizeColumn and/or colorColumn to change the size and/or color of the symbols according to the values in the column.
|
||||||
|
BIN
screenshots/scatter.png
Normal file
BIN
screenshots/scatter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
screenshots/scatter_small.png
Normal file
BIN
screenshots/scatter_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
Loading…
Reference in New Issue
Block a user