Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 51 additions & 21 deletions python/plugins/processing/algs/qgis/PolarPlot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
***************************************************************************
BarPlot.py
PolarPlot.py
---------------------
Date : January 2013
Copyright : (C) 2013 by Victor Olaya
Expand All @@ -26,6 +26,8 @@
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterFileDestination,
QgsFeatureRequest,
QgsProcessingParameterString,
)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import vector
Expand All @@ -36,7 +38,9 @@
class PolarPlot(QgisAlgorithm):
INPUT = "INPUT"
OUTPUT = "OUTPUT"
NAME_FIELD = "NAME_FIELD"
VALUE_FIELD = "VALUE_FIELD"
TITLE = "TITLE"

def group(self):
return self.tr("Plots")
Expand All @@ -51,6 +55,14 @@ def initAlgorithm(self, config=None):
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.DataType.Any,
)
)
self.addParameter(
QgsProcessingParameterField(
self.VALUE_FIELD,
Expand All @@ -59,27 +71,29 @@ def initAlgorithm(self, config=None):
type=QgsProcessingParameterField.DataType.Numeric,
)
)

self.addParameter(
QgsProcessingParameterFileDestination(
self.OUTPUT, self.tr("Polar plot"), self.tr("HTML files (*.html)")
self.OUTPUT, self.tr("Polar bar plot"), self.tr("HTML files (*.html)")
)
)
self.addParameter(
QgsProcessingParameterString(self.TITLE, self.tr("Title"), optional=True)
)

def name(self):
return "polarplot"

def displayName(self):
return self.tr("Polar plot")
return self.tr("Polar bar plot")

def shortDescription(self):
return self.tr(
"Generates a polar plot based on the value of an input vector layer."
"Creates a polar bar plot based on values grouped by a category field."
)

def shortHelpString(self):
return self.tr(
"This algorithm generates a polar plot based on the value of an input vector layer."
"This algorithm creates a polar bar plot based on values grouped by a category field."
)

def processAlgorithm(self, parameters, context, feedback):
Expand All @@ -98,37 +112,53 @@ def processAlgorithm(self, parameters, context, feedback):
)
)

try:
import numpy as np
except ImportError:
raise QgsProcessingException(
QCoreApplication.translate(
"PolarPlot",
"This algorithm requires the Python “numpy” library. Please install this library and try again.",
)
)

source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(
self.invalidSourceError(parameters, self.INPUT)
)

namefieldname = self.parameterAsString(parameters, self.NAME_FIELD, context)
valuefieldname = self.parameterAsString(parameters, self.VALUE_FIELD, context)
title = self.parameterAsString(parameters, self.TITLE, context)

if title.strip() == "":
title = None

output = self.parameterAsFileOutput(parameters, self.OUTPUT, context)

values = vector.values(source, valuefieldname)

# Load a vector of categories
category_index = source.fields().lookupField(namefieldname)
categories = vector.convert_nulls(
[
i[namefieldname]
for i in source.getFeatures(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it's possible to avoid a double for loop?

Maybe first : create a request = (QgsFeatureRequest...

and iterate over for feature in source.getFeatures(request):
...

I didn't test my idea.

QgsFeatureRequest()
.setFlags(QgsFeatureRequest.Flag.NoGeometry)
.setSubsetOfAttributes([category_index])
)
],
"<NULL>",
)
# Sum up values by category
category_sums = {category: 0 for category in set(categories)}
for idx in range(len(categories)):
category_sums[categories[idx]] += values[valuefieldname][idx]

data = [
go.Barpolar(
r=values[valuefieldname],
theta=np.degrees(
np.arange(0.0, 2 * np.pi, 2 * np.pi / len(values[valuefieldname]))
),
r=list(category_sums.values()),
theta=list(category_sums.keys()),
)
]

plt.offline.plot(data, filename=output, auto_open=False)
fig = go.Figure(
data=data,
layout_title_text=title,
)

fig.write_html(output)

return {self.OUTPUT: output}