# Creating percentile class breaks in vector data QGIS using numpy.percentile

I am having trouble making percentile breaks in my point data for a numeric field.

I have looked at these similar questions, most seem to relate to raster though:

I want breaks at 25, 50, 75, 90, 95, and 98 percentiles. Here is my code:

``````case
when ag_ppm <= q1(ag_ppm)
then '< 25th: ' || minimum("ag_ppm") || ' - ' || q1(ag_ppm)
when ag_ppm < median(ag_ppm) AND ag_ppm > q1(ag_ppm)
then '25th to 50th: ' || (q1(ag_ppm)+0.001) || ' - ' || median(ag_ppm)
when ag_ppm <= q3(ag_ppm) AND ag_ppm > median(ag_ppm)
then '50th to 75th: ' || (median(ag_ppm)+0.001) || ' - ' || q3(ag_ppm)
when ag_ppm <= percentile(90,ag_ppm) AND ag_ppm > q3(ag_ppm)
then '75th to 90th: ' || (q3(ag_ppm)+0.001) || ' - ' || percentile(90,ag_ppm)
when ag_ppm <= percentile(95,ag_ppm) AND ag_ppm > percentile(90,ag_ppm)
then '90th to 95th: ' || (percentile(90,ag_ppm)+0.001) || ' - ' || percentile(95,ag_ppm)
when ag_ppm <= percentile(98,ag_ppm) AND ag_ppm > percentile(95,ag_ppm)
then '95th to 98th: ' || (percentile(95,ag_ppm)+0.001) || ' - ' || percentile(98,ag_ppm)
when ag_ppm <= max(ag_ppm) AND ag_ppm > percentile(98,ag_ppm)
then '> 98th: ' || (q3(ag_ppm)+0.001) || ' - ' || maximum(ag_ppm)
else 'NULL'
end
``````

Here is my code to create a percentile function in QGIS:

``````from qgis.core import *
from qgis.gui import *
import numpy as np

@qgsfunction(args='auto', group='Custom')
def percentile(per, field_name, feature, parent):
return float(np.percentile(np.array(field_name), per))
``````

However, when I run this it gives me numerous results for the percentile function. I think I need to add a group by clause in my code but not sure how.

UPDATE: all I needed to do was change array(ag_ppm) to array_agg(ag_ppm, project) since there is only 1 project shown at a time.

see code below:

``````case
when ag_ppm <= q1(ag_ppm)
then '<25th: ' || minimum("ag_ppm") || ' - ' || q1(ag_ppm)
when ag_ppm < median(ag_ppm) AND ag_ppm > q1(ag_ppm)
then '25th to 50th: ' || (q1(ag_ppm)+0.001) || ' - ' || median(ag_ppm)
when ag_ppm <= q3(ag_ppm) AND ag_ppm > median(ag_ppm)
then '50th to 75th: ' || (median(ag_ppm)+0.001) || ' - ' || q3(ag_ppm)
when ag_ppm <= percentile(90,array_agg(ag_ppm,project)) AND ag_ppm > q3(ag_ppm)
then '75th to 90th: ' || (q3(ag_ppm)+0.001) || ' - ' || percentile(90,array_agg(ag_ppm,project))
when ag_ppm <= percentile(95,array_agg(ag_ppm,project)) AND ag_ppm > percentile(90,ag_ppm)
then '90th to 95th: ' || (percentile(90,array_agg(ag_ppm,project))+0.001) || ' - ' || percentile(95,array_agg(ag_ppm,project))
when ag_ppm <= percentile(98,ag_ppm) AND ag_ppm > percentile(95,ag_ppm)
then '95th to 98th: ' || (percentile(95,array_agg(ag_ppm,project))+0.001) || ' - ' || percentile(98,array_agg(ag_ppm,project))
when ag_ppm <= maximum(ag_ppm) AND ag_ppm > percentile(98,array_agg(ag_ppm,project))
then '>98th: ' || (percentile(98,array_agg(ag_ppm,project))+0.001) || ' - ' || maximum(ag_ppm)
else 'NULL'
end
``````