Updated answer:
Below is a recipe to apply a graduated renderer based on values in an attribute field, specifying the number of classes and color ramp.
# Set layer name and desired paremeters
layer_name = 'Your_layer_name'
ramp_name = 'Spectral'
value_field = 'Your_field_name'
num_classes = 5
classification_method = QgsClassificationEqualInterval()
#You can use any of these classification method classes:
#QgsClassificationQuantile()
#QgsClassificationEqualInterval()
#QgsClassificationJenks()
#QgsClassificationPrettyBreaks()
#QgsClassificationLogarithmic()
#QgsClassificationStandardDeviation()
layer = QgsProject().instance().mapLayersByName(layer_name)[0]
# change format settings as necessary
format = QgsRendererRangeLabelFormat()
format.setFormat("%1 - %2")
format.setPrecision(2)
format.setTrimTrailingZeroes(True)
default_style = QgsStyle().defaultStyle()
color_ramp = default_style.colorRamp(ramp_name)
renderer = QgsGraduatedSymbolRenderer()
renderer.setClassAttribute(value_field)
renderer.setClassificationMethod(classification_method)
renderer.setLabelFormat(format)
renderer.updateClasses(layer, num_classes)
renderer.updateColorRamp(color_ramp)
layer.setRenderer(renderer)
layer.triggerRepaint()
I will leave the original answer below:
I have been through the same experience before, and (I may be wrong) but as far as I am aware, it is not possible to programmatically set a default color ramp and have it automatically applied. As you discovered, doing setSourceColorRamp()
just sets that color ramp in the symbology dialog- it doesn't apply it to the renderer range symbols.
You have to create each range, instantiate QgsSymbol()
objects, set colors to them and pass those in to a QgsRendererRange()
constructor, together with the range and legend values.
It's a bit hacky, but I knocked out the script below which will create a graduated symbology with 10 classes (like your example above) in a basic spectral color ramp. Just change the layer name to match yours:
layer = QgsProject().instance().mapLayersByName('Your_Layer_Name')[0]
vals = []
fld = 'AREA'
for f in layer.getFeatures():
vals.append(f[fld])
# If you don't like these colors, change them out for ones you do, using hexcodes,
# RGB codes etc. as long as the items in this list are valid strings you
# can pass to a QColor constructor
colors = ['#0011FF', '#0061FF', '#00D4FF', '#00FF66', '#00FF00', '#E5FF32', '#FCFC0C', '#FF9F00', '#FF3F00', '#FF0000']
lower = sorted(vals)[0]
upper = sorted(vals)[-1]
step = (upper-lower)/len(colors)
range_list = []
for c in colors:
cat = [lower, lower+step, c]
sym = QgsSymbol.defaultSymbol(layer.geometryType())
sym.setColor(QColor(cat[2]))
rng = QgsRendererRange(cat[0], cat[1], sym, '{0:.1f}-{1:.1f}'.format(cat[0], cat[1]))
range_list.append(rng)
lower = (lower+step)+0.1
renderer = QgsGraduatedSymbolRenderer(fld, range_list)
layer.setRenderer(renderer)
layer.triggerRepaint()
Below is the result of this script run on a sample dataset- IBRA Bioregions of Australia, obtaining the graduation values from the "SHAPE_Area" field.

Based on the comment by @Cushen below, you could obtain a range of color values from an existing styled layer with a graduated ramp of the required number of classes and read those colors into a list object with a simple list comprehension:
styled_layer = iface.activeLayer() # existing layer styled with desired color ramp
colors = [s.color().name() for s in styled_layer.renderer().symbols(QgsRenderContext())]
myRangeList
includes a list of QgsRendererRanges, instantiated with these variables: myRange = QgsRendererRange(myMin, myMax, mySymbol, myLabel). I basically followed the example from the PyQGIS cookbook here: docs.qgis.org/testing/pdf/en/…, on page 37.