QGIS API Documentation  3.17.0-Master (a035f434f4)
qgshistogram.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgshistogram.cpp
3  ----------------
4  begin : May 2015
5  copyright : (C) 2015 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgshistogram.h"
19 
20 #include "qgsstatisticalsummary.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsvectorlayerutils.h"
23 
24 void QgsHistogram::prepareValues()
25 {
26  std::sort( mValues.begin(), mValues.end() );
27 
30  s.calculate( mValues );
31  mMin = s.min();
32  mMax = s.max();
33  mIQR = s.interQuartileRange();
34 }
35 
36 void QgsHistogram::setValues( const QList<double> &values )
37 {
38  mValues = values;
39  prepareValues();
40 }
41 
42 bool QgsHistogram::setValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, QgsFeedback *feedback )
43 {
44  mValues.clear();
45  if ( !layer )
46  return false;
47 
48  bool ok;
49  mValues = QgsVectorLayerUtils::getDoubleValues( layer, fieldOrExpression, ok, false, nullptr, feedback );
50  if ( !ok )
51  return false;
52 
53  prepareValues();
54  return true;
55 }
56 
58 {
59  //Freedman-Diaconis rule
60  return 2.0 * mIQR * std::pow( mValues.count(), -1 / 3.0 );
61 }
62 
64 {
65  return std::ceil( ( mMax - mMin ) / optimalBinWidth() );
66 }
67 
68 QList<double> QgsHistogram::binEdges( int bins ) const
69 {
70  double binWidth = ( mMax - mMin ) / bins;
71 
72  QList<double> edges;
73  edges.reserve( bins + 1 );
74  edges << mMin;
75  double current = mMin;
76  for ( int i = 0; i < bins; ++i )
77  {
78  current += binWidth;
79  edges << current;
80  }
81  return edges;
82 }
83 
84 QList<int> QgsHistogram::counts( int bins ) const
85 {
86  QList<double> edges = binEdges( bins );
87 
88  QList<int> binCounts;
89  binCounts.reserve( bins );
90  int currentValueIndex = 0;
91  for ( int i = 0; i < bins; ++i )
92  {
93  int count = 0;
94  while ( currentValueIndex < mValues.count() && mValues.at( currentValueIndex ) < edges.at( i + 1 ) )
95  {
96  count++;
97  currentValueIndex++;
98  if ( currentValueIndex >= mValues.count() )
99  break;
100  }
101  binCounts << count;
102  }
103 
104  if ( currentValueIndex < mValues.count() )
105  {
106  //last value needs to be added
107  binCounts[ bins - 1 ] = binCounts.last() + 1;
108  }
109 
110  return binCounts;
111 }
112 
113 
QList< double > binEdges(int bins) const
Returns a list of edges for the histogram for a specified number of bins.
static QList< double > getDoubleValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr, QgsFeedback *feedback=nullptr)
Fetches all double values from a specified field name or expression.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:43
void setValues(const QList< double > &values)
Assigns numeric source values for the histogram.
QList< int > counts(int bins) const
Returns the calculated list of the counts for the histogram bins.
void setStatistics(QgsStatisticalSummary::Statistics stats)
Sets flags which specify which statistics will be calculated.
Calculator for summary statistics for a list of doubles.
Represents a vector layer which manages a vector based data sets.
int optimalNumberBins() const
Returns the optimal number of bins for the source values, calculated using the Freedman-Diaconis rule...
double optimalBinWidth() const
Calculates the optimal bin width using the Freedman-Diaconis rule.