Skip to content

Commit 16ac437

Browse files
committed
[processing] Fix bar and box plot exception when category field has NULL values
1 parent 31a8f3f commit 16ac437

File tree

4 files changed

+27
-7
lines changed

4 files changed

+27
-7
lines changed

python/plugins/processing/algs/qgis/BarPlot.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
import plotly.graph_objs as go
3030

3131

32-
from qgis.core import (QgsProcessingParameterFeatureSource,
32+
from qgis.core import (QgsFeatureRequest,
33+
QgsProcessingParameterFeatureSource,
3334
QgsProcessingParameterField,
3435
QgsProcessingException,
3536
QgsProcessingParameterFileDestination)
@@ -83,7 +84,7 @@ def processAlgorithm(self, parameters, context, feedback):
8384

8485
values = vector.values(source, valuefieldname)
8586

86-
x_var = [i[namefieldname] for i in source.getFeatures()]
87+
x_var = vector.convert_nulls([i[namefieldname] for i in source.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry))], '<NULL>')
8788

8889
data = [go.Bar(x=x_var,
8990
y=values[valuefieldname])]

python/plugins/processing/algs/qgis/BoxPlot.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def processAlgorithm(self, parameters, context, feedback):
9696
values = vector.values(source, valuefieldname)
9797

9898
x_index = source.fields().lookupField(namefieldname)
99-
x_var = [i[namefieldname] for i in source.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([x_index]))]
99+
x_var = vector.convert_nulls([i[namefieldname] for i in source.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([x_index]))], '<NULL>')
100100

101101
msdIndex = self.parameterAsEnum(parameters, self.MSD, context)
102102
msd = True

python/plugins/processing/tests/ToolsTest.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import os
2929
import shutil
3030

31-
from qgis.core import QgsVectorLayer
31+
from qgis.core import NULL, QgsVectorLayer
3232
from qgis.testing import start_app, unittest
3333

3434
from processing.tests.TestData import points
@@ -77,6 +77,17 @@ def testValues(self):
7777
self.assertEqual(res['id'], [1, 2, 3, 4, 5, 6, 7, 8, 9])
7878
self.assertEqual(res[2], [2, 1, 0, 2, 1, 0, 0, 0, 0])
7979

80+
def testConvertNulls(self):
81+
self.assertEqual(vector.convert_nulls([]), [])
82+
self.assertEqual(vector.convert_nulls([], '_'), [])
83+
self.assertEqual(vector.convert_nulls([NULL]), [None])
84+
self.assertEqual(vector.convert_nulls([NULL], '_'), ['_'])
85+
self.assertEqual(vector.convert_nulls([NULL], -1), [-1])
86+
self.assertEqual(vector.convert_nulls([1, 2, 3]), [1, 2, 3])
87+
self.assertEqual(vector.convert_nulls([1, None, 3]), [1, None, 3])
88+
self.assertEqual(vector.convert_nulls([1, NULL, 3, NULL]), [1, None, 3, None])
89+
self.assertEqual(vector.convert_nulls([1, NULL, 3, NULL], '_'), [1, '_', 3, '_'])
90+
8091

8192
if __name__ == '__main__':
8293
unittest.main()

python/plugins/processing/tools/vector.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28-
import csv
29-
30-
from qgis.core import (QgsWkbTypes,
28+
from qgis.core import (NULL,
3129
QgsFeatureRequest)
3230

3331

@@ -90,6 +88,16 @@ def values(source, *attributes):
9088
return ret
9189

9290

91+
def convert_nulls(values, replacement=None):
92+
"""
93+
Converts NULL items in a list of values to a replacement value (usually None)
94+
:param values: list of values
95+
:param replacement: value to use in place of NULL
96+
:return: converted list
97+
"""
98+
return [i if i != NULL else replacement for i in values]
99+
100+
93101
def checkMinDistance(point, index, distance, points):
94102
"""Check if distance from given point to all other points is greater
95103
than given value.

0 commit comments

Comments
 (0)