2017-04-12 09:17:46 -05:00
# -*- coding: utf-8 -*-
"""
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
BarPlot . py
- - - - - - - - - - - - - - - - - - - - -
Date : March 2015
Copyright : ( C ) 2017 by Matteo Ghetta
Email : matteo dot ghetta at gmail dot com
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
"""
__author__ = ' Matteo Ghetta '
__date__ = ' March 2017 '
__copyright__ = ' (C) 2017, Matteo Ghetta '
2019-11-17 12:33:50 +10:00
import warnings
2017-04-12 09:17:46 -05:00
2018-04-27 12:31:56 +10:00
from qgis . core import ( QgsProcessingException ,
QgsProcessingParameterFeatureSource ,
2017-08-30 07:28:25 +10:00
QgsProcessingParameterField ,
QgsProcessingParameterEnum ,
QgsProcessingParameterFileDestination ,
QgsFeatureRequest )
2017-06-06 13:41:42 +10:00
from processing . algs . qgis . QgisAlgorithm import QgisAlgorithm
2017-04-12 09:17:46 -05:00
from processing . tools import vector
2019-11-18 13:19:25 +01:00
from qgis . PyQt . QtCore import QCoreApplication
2017-04-12 09:17:46 -05:00
2017-05-19 11:27:16 +10:00
class BoxPlot ( QgisAlgorithm ) :
2017-04-12 09:17:46 -05:00
INPUT = ' INPUT '
OUTPUT = ' OUTPUT '
NAME_FIELD = ' NAME_FIELD '
VALUE_FIELD = ' VALUE_FIELD '
MSD = ' MSD '
def group ( self ) :
return self . tr ( ' Graphics ' )
2017-12-14 14:03:56 +02:00
def groupId ( self ) :
return ' graphics '
2017-05-15 13:40:38 +10:00
def __init__ ( self ) :
super ( ) . __init__ ( )
2017-07-10 16:31:14 +10:00
def initAlgorithm ( self , config = None ) :
2017-08-30 07:28:25 +10:00
self . addParameter ( QgsProcessingParameterFeatureSource ( self . INPUT ,
self . tr ( ' Input layer ' ) ) )
self . addParameter ( QgsProcessingParameterField ( self . NAME_FIELD ,
self . tr ( ' Category name field ' ) ,
parentLayerParameterName = self . INPUT ,
type = QgsProcessingParameterField . Any ) )
self . addParameter ( QgsProcessingParameterField ( self . VALUE_FIELD ,
self . tr ( ' Value field ' ) ,
parentLayerParameterName = self . INPUT ,
type = QgsProcessingParameterField . Numeric ) )
2017-04-12 09:17:46 -05:00
msd = [ self . tr ( ' Show Mean ' ) ,
self . tr ( ' Show Standard Deviation ' ) ,
self . tr ( ' Don \' t show Mean and Standard Deviation ' )
]
2017-08-30 07:28:25 +10:00
self . addParameter ( QgsProcessingParameterEnum (
2017-04-12 09:17:46 -05:00
self . MSD ,
self . tr ( ' Additional Statistic Lines ' ) ,
2017-08-30 07:28:25 +10:00
options = msd , defaultValue = 0 ) )
2017-04-12 09:17:46 -05:00
2017-08-30 07:28:25 +10:00
self . addParameter ( QgsProcessingParameterFileDestination ( self . OUTPUT , self . tr ( ' Box plot ' ) , self . tr ( ' HTML files (*.html) ' ) ) )
2017-04-12 09:17:46 -05:00
2017-05-15 13:40:38 +10:00
def name ( self ) :
return ' boxplot '
def displayName ( self ) :
return self . tr ( ' Box plot ' )
2017-05-15 16:19:46 +10:00
def processAlgorithm ( self , parameters , context , feedback ) :
2019-11-17 12:33:50 +10:00
try :
# importing plotly throws Python warnings from within the library - filter these out
with warnings . catch_warnings ( ) :
warnings . filterwarnings ( " ignore " , category = ResourceWarning )
warnings . filterwarnings ( " ignore " , category = ImportWarning )
import plotly as plt
import plotly . graph_objs as go
except ImportError :
2019-11-18 13:19:25 +01:00
raise QgsProcessingException ( QCoreApplication . translate ( ' BoxPlot ' , ' This algorithm requires the Python “plotly” library. Please install this library and try again. ' ) )
2019-11-17 12:33:50 +10:00
2017-08-30 07:28:25 +10:00
source = self . parameterAsSource ( parameters , self . INPUT , context )
2018-04-27 12:31:56 +10:00
if source is None :
raise QgsProcessingException ( self . invalidSourceError ( parameters , self . INPUT ) )
2017-08-30 07:28:25 +10:00
namefieldname = self . parameterAsString ( parameters , self . NAME_FIELD , context )
valuefieldname = self . parameterAsString ( parameters , self . VALUE_FIELD , context )
2017-04-12 09:17:46 -05:00
2017-08-30 07:28:25 +10:00
output = self . parameterAsFileOutput ( parameters , self . OUTPUT , context )
2017-04-12 09:17:46 -05:00
2017-08-30 07:28:25 +10:00
values = vector . values ( source , valuefieldname )
2017-04-12 09:17:46 -05:00
2017-08-30 07:28:25 +10:00
x_index = source . fields ( ) . lookupField ( namefieldname )
2018-06-20 07:28:07 +10:00
x_var = vector . convert_nulls ( [ i [ namefieldname ] for i in source . getFeatures ( QgsFeatureRequest ( ) . setFlags ( QgsFeatureRequest . NoGeometry ) . setSubsetOfAttributes ( [ x_index ] ) ) ] , ' <NULL> ' )
2017-04-12 09:17:46 -05:00
2017-08-30 07:28:25 +10:00
msdIndex = self . parameterAsEnum ( parameters , self . MSD , context )
2017-04-12 09:17:46 -05:00
msd = True
if msdIndex == 1 :
msd = ' sd '
elif msdIndex == 2 :
msd = False
data = [ go . Box (
x = x_var ,
y = values [ valuefieldname ] ,
boxmean = msd ) ]
plt . offline . plot ( data , filename = output , auto_open = False )
2017-08-30 07:28:25 +10:00
return { self . OUTPUT : output }