mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +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>
|
||||
<td>\image html beeswarmplot_small.png
|
||||
<td> JKQTPSingleColumnSymbolsGraph
|
||||
<tr>
|
||||
<td>\image html scatter_small.png
|
||||
<td> JKQTPXYScatterGraph, JKQTPXYScatterErrorGraph
|
||||
<tr>
|
||||
<td>\image html symbols_and_styles_small.png
|
||||
<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: 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 simple scatter plot JKQTPXYScatterGraph</li>
|
||||
</ul></li>
|
||||
|
||||
<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
|
||||
|
||||
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"
|
||||
|
||||
\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.
|
||||
|
||||
\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
|
||||
|
||||
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