Files
2024-06-28 12:23:19 +02:00

113 lines
5.6 KiB
Python

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
QgsFeatureSink,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterField,
QgsProcessingParameterFileDestination,
QgsProcessingParameterNumber,
QgsProcessingParameterString,
QgsProcessingParameterBoolean)
from qgis import processing
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
class matplotlibHist(QgsProcessingAlgorithm):
INPUT = 'INPUT'
ATTRIBUTE = 'ATTRIBUTE'
MAX_VALUE = 'MAX_VALUE'
PLOT_OUTPUT = 'PLOT_OUTPUT'
FIG_WIDTH = 'FIG_WIDTH'
FIG_HEIGHT = 'FIG_HEIGHT'
BINS = 'BINS'
ALPHA = 'ALPHA'
COLOR = 'COLOR'
SHOW_GRID = 'SHOW_GRID'
PLOT_TITLE = 'PLOT_TITLE'
X_LABEL = 'X_LABEL'
Y_LABEL = 'Y_LABEL'
def tr(self, string):
return QCoreApplication.translate('Processing', string)
def createInstance(self):
return matplotlibHist()
def name(self):
return 'Histogram'
def displayName(self):
return self.tr('Histogram')
def group(self):
return self.tr('matplotlib vector')
def groupId(self):
return 'matplotlib vector'
def shortHelpString(self):
return self.tr("Generates a histogram plot for a selected numeric attribute from an input layer.")
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,self.tr('Input layer'),[QgsProcessing.TypeVectorAnyGeometry]))
self.addParameter(QgsProcessingParameterField(self.ATTRIBUTE,self.tr('Attribute'),None,self.INPUT,QgsProcessingParameterField.Any))
self.addParameter(QgsProcessingParameterNumber(self.MAX_VALUE, self.tr('Maximum Value'), QgsProcessingParameterNumber.Double, None, optional=True))
self.addParameter(QgsProcessingParameterFileDestination('PLOT_OUTPUT',self.tr('Plot Output File'),'PNG Files (*.png)'))
self.addParameter(QgsProcessingParameterNumber(self.FIG_WIDTH,self.tr('Figure Width'), QgsProcessingParameterNumber.Double, 10))
self.addParameter(QgsProcessingParameterNumber(self.FIG_HEIGHT,self.tr('Figure Height'), QgsProcessingParameterNumber.Double, 6))
self.addParameter(QgsProcessingParameterNumber(self.BINS, self.tr('Number of Bins'), QgsProcessingParameterNumber.Integer, 30 ))
self.addParameter(QgsProcessingParameterNumber(self.ALPHA,self.tr('Alpha Transparency'), QgsProcessingParameterNumber.Double, 0.7))
self.addParameter(QgsProcessingParameterString(self.COLOR,self.tr('Color'), defaultValue='blue'))
self.addParameter(QgsProcessingParameterBoolean(self.SHOW_GRID,self.tr('Show Grid'), defaultValue=True))
self.addParameter(QgsProcessingParameterString(self.PLOT_TITLE, self.tr('Plot Title'), defaultValue=' '))
self.addParameter(QgsProcessingParameterString(self.X_LABEL, self.tr('X-axis Label'), defaultValue=' '))
self.addParameter(QgsProcessingParameterString(self.Y_LABEL, self.tr('Y-axis Label'), defaultValue='Frequency'))
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
attribute_name = self.parameterAsString(parameters, self.ATTRIBUTE, context)
attribute_values = []
max_value = self.parameterAsDouble(parameters, self.MAX_VALUE, context) if parameters[self.MAX_VALUE] is not None else max(attribute_values)
plot_output_path = self.parameterAsFileOutput(parameters, 'PLOT_OUTPUT', context)
fig_width = self.parameterAsDouble(parameters, self.FIG_WIDTH, context)
fig_height = self.parameterAsDouble(parameters, self.FIG_HEIGHT, context)
bins = self.parameterAsInt(parameters, self.BINS, context)
alpha = self.parameterAsDouble(parameters, self.ALPHA, context)
color = self.parameterAsString(parameters, self.COLOR, context)
show_grid = self.parameterAsBool(parameters, self.SHOW_GRID, context)
plot_title = self.parameterAsString(parameters, self.PLOT_TITLE, context)
x_label = self.parameterAsString(parameters, self.X_LABEL, context)
y_label = self.parameterAsString(parameters, self.Y_LABEL, context)
for feature in source.getFeatures():
attribute_value = feature[attribute_name]
if attribute_value is not None:
attribute_values.append(attribute_value)
if not attribute_values:
raise QgsProcessingException(self.tr("No attribute values found. Please check the selected attribute."))
try:
plt.figure(figsize=(fig_width,fig_height))
plt.hist(attribute_values, bins=bins,alpha=alpha, color=color, range=(min(attribute_values), max_value))
plt.title(plot_title if plot_title else 'Value Distribution by Category')
plt.xlabel(x_label if x_label else ' ')
plt.ylabel(y_label if y_label else 'Frequence')
if show_grid:
plt.grid(True)
else:
plt.grid(False)
plt.savefig(plot_output_path)
plt.close()
return {}
except Exception as e:
feedback.reportError(str(e))
return {}