mirror of
https://github.com/OPM/ResInsight.git
synced 2026-11-06 22:26:44 -06:00
Histogram Plot: add P10, mean and P90.
This commit is contained in:
1 parent
48f1597953
commit
b46e55bc21
9 files changed
+117
-80
No files matched your search
+14
-26
@@ -143,28 +143,19 @@ std::string RimEnsembleParameterHistogramDataSource::unitNameX() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimEnsembleParameterHistogramDataSource::valuesX( RimHistogramPlot::GraphType graphType ) const
|
||||
RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
|
||||
RimHistogramPlot::FrequencyType frequencyType ) const
|
||||
{
|
||||
if ( !m_ensemble ) return {};
|
||||
RimHistogramDataSource::HistogramResult result;
|
||||
|
||||
if ( !m_ensemble ) return result;
|
||||
|
||||
auto parameter = m_ensemble->ensembleParameter( m_parameter );
|
||||
if ( !parameter.isNumeric() || !parameter.isValid() ) return {};
|
||||
if ( !parameter.isNumeric() || !parameter.isValid() ) return result;
|
||||
|
||||
double min = parameter.minValue;
|
||||
double max = parameter.maxValue;
|
||||
return computeHistogramBins( min, max, m_numBins, graphType );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimEnsembleParameterHistogramDataSource::valuesY( RimHistogramPlot::GraphType graphType,
|
||||
RimHistogramPlot::FrequencyType frequencyType ) const
|
||||
{
|
||||
if ( !m_ensemble ) return {};
|
||||
|
||||
auto parameter = m_ensemble->ensembleParameter( m_parameter );
|
||||
if ( !parameter.isNumeric() || !parameter.isValid() ) return {};
|
||||
double min = parameter.minValue;
|
||||
double max = parameter.maxValue;
|
||||
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
|
||||
|
||||
std::vector<double> values;
|
||||
for ( const QVariant& v : parameter.values )
|
||||
@@ -172,20 +163,17 @@ std::vector<double> RimEnsembleParameterHistogramDataSource::valuesY( RimHistogr
|
||||
values.push_back( v.toDouble() );
|
||||
}
|
||||
|
||||
double min = parameter.minValue;
|
||||
double max = parameter.maxValue;
|
||||
|
||||
std::vector<size_t> histogram;
|
||||
RigHistogramCalculator histCalc( min, max, m_numBins, &histogram );
|
||||
histCalc.addData( values );
|
||||
|
||||
double p10 = histCalc.calculatePercentil( 0.1, RigStatisticsMath::PercentileStyle::REGULAR );
|
||||
double p50 = histCalc.calculatePercentil( 0.5, RigStatisticsMath::PercentileStyle::REGULAR );
|
||||
double p90 = histCalc.calculatePercentil( 0.9, RigStatisticsMath::PercentileStyle::REGULAR );
|
||||
result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType );
|
||||
|
||||
RiaLogging::info( QString( "%1: P10=%2 Mean=%3 P90=%4" ).arg( QString::fromStdString( name() ) ).arg( p10 ).arg( p50 ).arg( p90 ) );
|
||||
result.p10 = histCalc.calculatePercentil( 0.1, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
result.mean = histCalc.calculatePercentil( 0.5, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
result.p90 = histCalc.calculatePercentil( 0.9, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
|
||||
return computeHistogramFrequencies( histogram, graphType, frequencyType );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
+1
-2
@@ -43,8 +43,7 @@ public:
|
||||
std::string unitNameX() const override;
|
||||
std::string unitNameY() const override;
|
||||
|
||||
std::vector<double> valuesX( RimHistogramPlot::GraphType graphType ) const override;
|
||||
std::vector<double> valuesY( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
|
||||
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
|
||||
|
||||
std::string name() const override;
|
||||
|
||||
|
||||
+13
-25
@@ -229,43 +229,31 @@ std::vector<double> RimEnsembleSummaryVectorHistogramDataSource::extractValuesFr
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimEnsembleSummaryVectorHistogramDataSource::valuesX( RimHistogramPlot::GraphType graphType ) const
|
||||
RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
|
||||
RimHistogramPlot::FrequencyType frequencyType ) const
|
||||
{
|
||||
RimHistogramDataSource::HistogramResult result;
|
||||
|
||||
std::vector<double> values = extractValuesFromEnsemble();
|
||||
if ( values.empty() ) return {};
|
||||
if ( values.empty() ) return result;
|
||||
|
||||
auto [min_it, max_it] = std::minmax_element( values.begin(), values.end() );
|
||||
|
||||
double min = *min_it;
|
||||
double max = *max_it;
|
||||
return computeHistogramBins( min, max, m_numBins, graphType );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimEnsembleSummaryVectorHistogramDataSource::valuesY( RimHistogramPlot::GraphType graphType,
|
||||
RimHistogramPlot::FrequencyType frequencyType ) const
|
||||
{
|
||||
std::vector<double> values = extractValuesFromEnsemble();
|
||||
if ( values.empty() ) return {};
|
||||
|
||||
auto [min_it, max_it] = std::minmax_element( values.begin(), values.end() );
|
||||
|
||||
double min = *min_it;
|
||||
double max = *max_it;
|
||||
double min = *min_it;
|
||||
double max = *max_it;
|
||||
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
|
||||
|
||||
std::vector<size_t> histogram;
|
||||
RigHistogramCalculator histCalc( min, max, m_numBins, &histogram );
|
||||
histCalc.addData( values );
|
||||
|
||||
double p10 = histCalc.calculatePercentil( 0.1, RigStatisticsMath::PercentileStyle::REGULAR );
|
||||
double p50 = histCalc.calculatePercentil( 0.5, RigStatisticsMath::PercentileStyle::REGULAR );
|
||||
double p90 = histCalc.calculatePercentil( 0.9, RigStatisticsMath::PercentileStyle::REGULAR );
|
||||
result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType );
|
||||
|
||||
RiaLogging::info( QString( "%1: P10=%2 Mean=%3 P90=%4" ).arg( QString::fromStdString( name() ) ).arg( p10 ).arg( p50 ).arg( p90 ) );
|
||||
result.p10 = histCalc.calculatePercentil( 0.1, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
result.mean = histCalc.calculatePercentil( 0.5, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
result.p90 = histCalc.calculatePercentil( 0.9, RigStatisticsMath::PercentileStyle::SWITCHED );
|
||||
|
||||
return computeHistogramFrequencies( histogram, graphType, frequencyType );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
+1
-2
@@ -48,8 +48,7 @@ public:
|
||||
std::string unitNameX() const override;
|
||||
std::string unitNameY() const override;
|
||||
|
||||
std::vector<double> valuesX( RimHistogramPlot::GraphType graphType ) const override;
|
||||
std::vector<double> valuesY( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
|
||||
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
|
||||
|
||||
std::string name() const override;
|
||||
|
||||
|
||||
+11
-13
@@ -156,27 +156,25 @@ std::string RimGridStatisticsHistogramDataSource::unitNameX() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimGridStatisticsHistogramDataSource::valuesX( RimHistogramPlot::GraphType graphType ) const
|
||||
RimHistogramDataSource::HistogramResult RimGridStatisticsHistogramDataSource::compute( RimHistogramPlot::GraphType graphType,
|
||||
RimHistogramPlot::FrequencyType frequencyType ) const
|
||||
{
|
||||
RimHistogramDataSource::HistogramResult result;
|
||||
|
||||
RigHistogramData histogramData = createStatisticsData();
|
||||
if ( !histogramData.isHistogramVectorValid() ) return {};
|
||||
if ( !histogramData.isHistogramVectorValid() ) return result;
|
||||
|
||||
double min = histogramData.min;
|
||||
double max = histogramData.max;
|
||||
|
||||
return computeHistogramBins( min, max, m_numBins, graphType );
|
||||
}
|
||||
result.valuesX = computeHistogramBins( min, max, m_numBins, graphType );
|
||||
result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimGridStatisticsHistogramDataSource::valuesY( RimHistogramPlot::GraphType graphType,
|
||||
RimHistogramPlot::FrequencyType frequencyType ) const
|
||||
{
|
||||
RigHistogramData histogramData = createStatisticsData();
|
||||
if ( !histogramData.isHistogramVectorValid() ) return {};
|
||||
result.p10 = histogramData.p10;
|
||||
result.mean = histogramData.mean;
|
||||
result.p90 = histogramData.p90;
|
||||
|
||||
return computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
+1
-2
@@ -44,8 +44,7 @@ public:
|
||||
std::string unitNameX() const override;
|
||||
std::string unitNameY() const override;
|
||||
|
||||
std::vector<double> valuesX( RimHistogramPlot::GraphType graphType ) const override;
|
||||
std::vector<double> valuesY( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
|
||||
HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override;
|
||||
|
||||
std::string name() const override;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "RimHistogramCurve.h"
|
||||
|
||||
#include "RiaColorTools.h"
|
||||
#include "RiaGuiApplication.h"
|
||||
#include "RiaPlotDefines.h"
|
||||
|
||||
@@ -28,13 +29,17 @@
|
||||
#include "RimProject.h"
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "RiuPlotAnnotationTool.h"
|
||||
#include "RiuPlotAxis.h"
|
||||
#include "RiuPlotCurve.h"
|
||||
#include "RiuPlotMainWindow.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimHistogramCurve, "HistogramCurve" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -49,10 +54,14 @@ RimHistogramCurve::RimHistogramCurve()
|
||||
CAF_PDM_InitFieldNoDefault( &m_dataSource, "DataSource", "Data Source" );
|
||||
m_dataSource.uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
CAF_PDM_InitField( &m_showPercentiles, "ShowPercentiles", true, "Show P10, Mean, and P90" );
|
||||
|
||||
setSymbolSkipDistance( 10.0f );
|
||||
setLineThickness( 2 );
|
||||
|
||||
setDeletable( true );
|
||||
|
||||
m_annotationTool = std::make_unique<RiuPlotAnnotationTool>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -128,7 +137,7 @@ std::vector<double> RimHistogramCurve::valuesY() const
|
||||
if ( m_dataSource )
|
||||
{
|
||||
RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
|
||||
return m_dataSource()->valuesY( plot->graphType(), plot->frequencyType() );
|
||||
return m_dataSource()->compute( plot->graphType(), plot->frequencyType() ).valuesY;
|
||||
}
|
||||
else
|
||||
return {};
|
||||
@@ -142,7 +151,7 @@ std::vector<double> RimHistogramCurve::valuesX() const
|
||||
if ( m_dataSource )
|
||||
{
|
||||
RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
|
||||
return m_dataSource()->valuesX( plot->graphType() );
|
||||
return m_dataSource()->compute( plot->graphType(), plot->frequencyType() ).valuesX;
|
||||
}
|
||||
else
|
||||
return {};
|
||||
@@ -238,15 +247,45 @@ void RimHistogramCurve::onLoadDataAndUpdate( bool updateParentPlot )
|
||||
|
||||
updateConnectedEditors();
|
||||
|
||||
if ( isChecked() )
|
||||
{
|
||||
std::vector<double> curveValuesX = valuesX();
|
||||
std::vector<double> curveValuesY = valuesY();
|
||||
m_annotationTool->detachAllAnnotations();
|
||||
|
||||
if ( isChecked() && m_dataSource() )
|
||||
{
|
||||
RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
|
||||
|
||||
auto result = m_dataSource->compute( plot->graphType(), plot->frequencyType() );
|
||||
|
||||
auto plot = firstAncestorOrThisOfTypeAsserted<RimHistogramPlot>();
|
||||
bool useLogarithmicScale = plot->isLogarithmicScaleEnabled( axisY() );
|
||||
|
||||
setSamplesFromXYValues( curveValuesX, curveValuesY, useLogarithmicScale );
|
||||
QColor color = RiaColorTools::toQColor( m_curveAppearance->color() );
|
||||
if ( plot->plotWidget() )
|
||||
{
|
||||
if ( m_showPercentiles() )
|
||||
{
|
||||
QwtPlot* qwtPlot = dynamic_cast<RiuQwtPlotWidget*>( plot->plotWidget() )->qwtPlot();
|
||||
|
||||
QString autoName = createCurveAutoName();
|
||||
std::map<QString, double> percentiles = { { QString( "P10: %1" ).arg( autoName ), result.p10 },
|
||||
{ QString( "Mean: %1" ).arg( autoName ), result.mean },
|
||||
{ QString( "P90: %1" ).arg( autoName ), result.p90 } };
|
||||
|
||||
for ( const auto& [name, value] : percentiles )
|
||||
{
|
||||
if ( !std::isinf( value ) )
|
||||
{
|
||||
m_annotationTool->attachAnnotationLine( qwtPlot,
|
||||
color,
|
||||
name,
|
||||
Qt::PenStyle::DashDotDotLine,
|
||||
value,
|
||||
RiaDefines::Orientation::VERTICAL,
|
||||
Qt::AlignmentFlag::AlignCenter );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setSamplesFromXYValues( result.valuesX, result.valuesY, useLogarithmicScale );
|
||||
}
|
||||
|
||||
if ( updateParentPlot && hasParentPlot() )
|
||||
@@ -306,6 +345,8 @@ void RimHistogramCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi
|
||||
nameGroup->add( &m_showLegend );
|
||||
RimPlotCurve::curveNameUiOrdering( *nameGroup );
|
||||
|
||||
uiOrdering.add( &m_showPercentiles );
|
||||
|
||||
uiOrdering.skipRemainingFields();
|
||||
}
|
||||
|
||||
@@ -345,6 +386,10 @@ void RimHistogramCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedFiel
|
||||
plot->updateAxes();
|
||||
dataChanged.send();
|
||||
}
|
||||
else if ( changedField == &m_showPercentiles )
|
||||
{
|
||||
loadAndUpdate = true;
|
||||
}
|
||||
|
||||
if ( loadAndUpdate )
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiuPlotAnnotationTool.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
@@ -86,4 +87,8 @@ private:
|
||||
caf::PdmPtrField<RimPlotAxisPropertiesInterface*> m_xPlotAxisProperties;
|
||||
|
||||
caf::PdmChildField<RimHistogramDataSource*> m_dataSource;
|
||||
|
||||
caf::PdmField<bool> m_showPercentiles;
|
||||
|
||||
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
|
||||
};
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafSignal.h"
|
||||
#include <limits>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@@ -32,6 +33,22 @@ class RimHistogramDataSource : public caf::PdmObject
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
struct HistogramResult
|
||||
{
|
||||
HistogramResult()
|
||||
: p10( std::numeric_limits<double>::infinity() )
|
||||
, p90( std::numeric_limits<double>::infinity() )
|
||||
, mean( std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<double> valuesX;
|
||||
std::vector<double> valuesY;
|
||||
double p10;
|
||||
double p90;
|
||||
double mean;
|
||||
};
|
||||
|
||||
RimHistogramDataSource();
|
||||
~RimHistogramDataSource() override;
|
||||
|
||||
@@ -40,8 +57,7 @@ public:
|
||||
virtual std::string unitNameX() const = 0;
|
||||
virtual std::string unitNameY() const = 0;
|
||||
|
||||
virtual std::vector<double> valuesX( RimHistogramPlot::GraphType graphType ) const = 0;
|
||||
virtual std::vector<double> valuesY( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const = 0;
|
||||
virtual HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const = 0;
|
||||
|
||||
virtual std::string name() const = 0;
|
||||
|
||||
|
||||
Reference in new issue
Block a user