[{"data":1,"prerenderedAt":1717},["ShallowReactive",2],{"doc:\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fset-vector-layer-symbol-color-pyqgis":3},{"id":4,"title":5,"body":6,"description":1710,"extension":1711,"meta":1712,"navigation":146,"path":1713,"seo":1714,"stem":1715,"__hash__":1716},"docs\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fset-vector-layer-symbol-color-pyqgis\u002Findex.md","Set Vector Layer Symbol Color in PyQGIS",{"type":7,"value":8,"toc":1694},"minimark",[9,13,32,37,67,71,93,97,100,217,252,256,269,396,419,423,426,615,660,664,669,831,854,858,865,1068,1091,1095,1098,1250,1276,1280,1283,1399,1416,1420,1427,1498,1501,1505,1526,1541,1557,1572,1588,1592,1607,1611,1628,1642,1656,1670,1674,1690],[10,11,5],"h1",{"id":12},"set-vector-layer-symbol-color-in-pyqgis",[14,15,16,17,21,22,25,26,31],"p",{},"Recolouring a layer is the single most common styling task in PyQGIS, and it is a one-liner once you know which object holds the colour. The short version: reach the renderer's symbol, call ",[18,19,20],"code",{},"setColor()"," with a ",[18,23,24],{},"QColor",", then repaint. This page is a focused recipe within the broader ",[27,28,30],"a",{"href":29},"\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002F","Programmatic Layer Styling in PyQGIS"," cluster, covering the fill colour, the outline colour, hex versus RGBA, the differences between marker, fill, and line layers, and how to make the change survive a project reload.",[33,34,36],"h2",{"id":35},"prerequisites","Prerequisites",[38,39,40,48,55,64],"ul",{},[41,42,43,47],"li",{},[44,45,46],"strong",{},"QGIS 3.34 LTR"," (Python 3.12), running code in the Python Console or a standalone script.",[41,49,50,51,54],{},"A loaded, valid vector layer with a ",[44,52,53],{},"single-symbol renderer"," (the default for a freshly added layer).",[41,56,57,59,60,63],{},[18,58,24],{}," imported from ",[18,61,62],{},"qgis.PyQt.QtGui",".",[41,65,66],{},"A basic grasp of the renderer → symbol → symbol-layer chain described in the parent cluster.",[33,68,70],{"id":69},"where-the-color-lives","Where the color lives",[14,72,73,74,76,77,79,80,84,85,88,89,92],{},"The colour you want to change is not a property of the layer directly — it is buried two levels down. The layer holds a renderer, the renderer holds a symbol, and the symbol holds one or more symbol layers that carry the actual ",[18,75,24],{},". That means there are two valid targets depending on intent: call ",[18,78,20],{}," on the ",[81,82,83],"em",{},"symbol"," for a quick flat recolour that touches every symbol layer, or call it on a specific ",[81,86,87],{},"symbol layer"," (",[18,90,91],{},"symbolLayer(0)",") when you need to keep the fill and outline independent. The recipes below cover both, plus the geometry-specific quirks and how to make the change permanent.",[33,94,96],{"id":95},"recipe-1-set-the-whole-symbols-color","Recipe 1: Set the whole symbol's color",[14,98,99],{},"For a flat recolour where the fill and any outline should take the same base colour, set it on the symbol itself. The colour cascades to every symbol layer in the stack.",[101,102,107],"pre",{"className":103,"code":104,"language":105,"meta":106,"style":106},"language-python shiki shiki-themes github-dark","from qgis.core import QgsProject\nfrom qgis.PyQt.QtGui import QColor\n\nlayer = QgsProject.instance().mapLayersByName(\"districts\")[0]\n\nsymbol = layer.renderer().symbol()\nsymbol.setColor(QColor(\"#0f766e\"))   # teal, from a hex string\n\nlayer.triggerRepaint()\n","python","",[18,108,109,128,141,148,174,179,190,206,211],{"__ignoreMap":106},[110,111,114,118,122,125],"span",{"class":112,"line":113},"line",1,[110,115,117],{"class":116},"snl16","from",[110,119,121],{"class":120},"s95oV"," qgis.core ",[110,123,124],{"class":116},"import",[110,126,127],{"class":120}," QgsProject\n",[110,129,131,133,136,138],{"class":112,"line":130},2,[110,132,117],{"class":116},[110,134,135],{"class":120}," qgis.PyQt.QtGui ",[110,137,124],{"class":116},[110,139,140],{"class":120}," QColor\n",[110,142,144],{"class":112,"line":143},3,[110,145,147],{"emptyLinePlaceholder":146},true,"\n",[110,149,151,154,157,160,164,167,171],{"class":112,"line":150},4,[110,152,153],{"class":120},"layer ",[110,155,156],{"class":116},"=",[110,158,159],{"class":120}," QgsProject.instance().mapLayersByName(",[110,161,163],{"class":162},"sU2Wk","\"districts\"",[110,165,166],{"class":120},")[",[110,168,170],{"class":169},"sDLfK","0",[110,172,173],{"class":120},"]\n",[110,175,177],{"class":112,"line":176},5,[110,178,147],{"emptyLinePlaceholder":146},[110,180,182,185,187],{"class":112,"line":181},6,[110,183,184],{"class":120},"symbol ",[110,186,156],{"class":116},[110,188,189],{"class":120}," layer.renderer().symbol()\n",[110,191,193,196,199,202],{"class":112,"line":192},7,[110,194,195],{"class":120},"symbol.setColor(QColor(",[110,197,198],{"class":162},"\"#0f766e\"",[110,200,201],{"class":120},"))   ",[110,203,205],{"class":204},"sAwPA","# teal, from a hex string\n",[110,207,209],{"class":112,"line":208},8,[110,210,147],{"emptyLinePlaceholder":146},[110,212,214],{"class":112,"line":213},9,[110,215,216],{"class":120},"layer.triggerRepaint()\n",[14,218,219,222,223,226,227,230,231,234,235,238,239,241,242,244,245,247,248,251],{},[44,220,221],{},"Breakdown:"," ",[18,224,225],{},"layer.renderer()"," returns the ",[18,228,229],{},"QgsSingleSymbolRenderer","; ",[18,232,233],{},".symbol()"," returns its ",[18,236,237],{},"QgsSymbol",". ",[18,240,20],{}," on the symbol is a shortcut that applies the colour to all of its symbol layers at once. ",[18,243,24],{}," accepts a hex string directly, so ",[18,246,198],{}," needs no parsing. ",[18,249,250],{},"triggerRepaint()"," schedules the canvas redraw.",[33,253,255],{"id":254},"recipe-2-set-fill-and-outline-colors-separately","Recipe 2: Set fill and outline colors separately",[14,257,258,259,261,262,264,265,268],{},"Most cartographic work wants a fill in one colour and a contrasting outline in another. That requires addressing the symbol layer with ",[18,260,91],{}," and calling ",[18,263,20],{}," for the fill and ",[18,266,267],{},"setStrokeColor()"," for the outline.",[101,270,272],{"className":103,"code":271,"language":105,"meta":106,"style":106},"from qgis.core import QgsProject\nfrom qgis.PyQt.QtGui import QColor\n\nlayer = QgsProject.instance().mapLayersByName(\"districts\")[0]\nfill_layer = layer.renderer().symbol().symbolLayer(0)\n\nfill_layer.setColor(QColor(245, 158, 11))        # amber fill (RGB)\nfill_layer.setStrokeColor(QColor(\"#17211d\"))     # near-black outline\nfill_layer.setStrokeWidth(0.5)                   # outline width in mm\n\nlayer.triggerRepaint()\n",[18,273,274,284,294,298,314,329,333,358,372,386,391],{"__ignoreMap":106},[110,275,276,278,280,282],{"class":112,"line":113},[110,277,117],{"class":116},[110,279,121],{"class":120},[110,281,124],{"class":116},[110,283,127],{"class":120},[110,285,286,288,290,292],{"class":112,"line":130},[110,287,117],{"class":116},[110,289,135],{"class":120},[110,291,124],{"class":116},[110,293,140],{"class":120},[110,295,296],{"class":112,"line":143},[110,297,147],{"emptyLinePlaceholder":146},[110,299,300,302,304,306,308,310,312],{"class":112,"line":150},[110,301,153],{"class":120},[110,303,156],{"class":116},[110,305,159],{"class":120},[110,307,163],{"class":162},[110,309,166],{"class":120},[110,311,170],{"class":169},[110,313,173],{"class":120},[110,315,316,319,321,324,326],{"class":112,"line":176},[110,317,318],{"class":120},"fill_layer ",[110,320,156],{"class":116},[110,322,323],{"class":120}," layer.renderer().symbol().symbolLayer(",[110,325,170],{"class":169},[110,327,328],{"class":120},")\n",[110,330,331],{"class":112,"line":181},[110,332,147],{"emptyLinePlaceholder":146},[110,334,335,338,341,344,347,349,352,355],{"class":112,"line":192},[110,336,337],{"class":120},"fill_layer.setColor(QColor(",[110,339,340],{"class":169},"245",[110,342,343],{"class":120},", ",[110,345,346],{"class":169},"158",[110,348,343],{"class":120},[110,350,351],{"class":169},"11",[110,353,354],{"class":120},"))        ",[110,356,357],{"class":204},"# amber fill (RGB)\n",[110,359,360,363,366,369],{"class":112,"line":208},[110,361,362],{"class":120},"fill_layer.setStrokeColor(QColor(",[110,364,365],{"class":162},"\"#17211d\"",[110,367,368],{"class":120},"))     ",[110,370,371],{"class":204},"# near-black outline\n",[110,373,374,377,380,383],{"class":112,"line":213},[110,375,376],{"class":120},"fill_layer.setStrokeWidth(",[110,378,379],{"class":169},"0.5",[110,381,382],{"class":120},")                   ",[110,384,385],{"class":204},"# outline width in mm\n",[110,387,389],{"class":112,"line":388},10,[110,390,147],{"emptyLinePlaceholder":146},[110,392,394],{"class":112,"line":393},11,[110,395,216],{"class":120},[14,397,398,222,400,402,403,406,407,409,410,238,412,414,415,418],{},[44,399,221],{},[18,401,91],{}," is the bottom-most drawing layer — a ",[18,404,405],{},"QgsSimpleFillSymbolLayer"," for polygons. ",[18,408,20],{}," here affects only that layer's fill, leaving you free to set a different ",[18,411,267],{},[18,413,24],{}," is shown with three integers (0–255) to contrast with the hex form; both produce the same object. ",[18,416,417],{},"setStrokeWidth()"," is in millimetres by default, matching QGIS's symbol units.",[33,420,422],{"id":421},"recipe-3-color-by-geometry-type","Recipe 3: Color by geometry type",[14,424,425],{},"The setter names differ slightly between geometry types because the symbol layer classes differ. The snippet below detects the geometry and applies an appropriate colour and outline for each case.",[101,427,429],{"className":103,"code":428,"language":105,"meta":106,"style":106},"from qgis.core import QgsProject, QgsWkbTypes\nfrom qgis.PyQt.QtGui import QColor\n\nlayer = QgsProject.instance().mapLayersByName(\"features\")[0]\nsl = layer.renderer().symbol().symbolLayer(0)\ngtype = layer.geometryType()\n\nif gtype == QgsWkbTypes.PolygonGeometry:\n    sl.setColor(QColor(\"#22c55e\"))          # fill\n    sl.setStrokeColor(QColor(\"#15803d\"))    # outline\nelif gtype == QgsWkbTypes.LineGeometry:\n    sl.setColor(QColor(\"#2563eb\"))          # the line is the color\nelif gtype == QgsWkbTypes.PointGeometry:\n    sl.setColor(QColor(\"#b45309\"))          # marker fill\n    sl.setStrokeColor(QColor(\"#ffffff\"))    # marker outline \u002F halo\n\nlayer.triggerRepaint()\n",[18,430,431,442,452,456,473,486,496,500,514,528,542,554,567,579,592,605,610],{"__ignoreMap":106},[110,432,433,435,437,439],{"class":112,"line":113},[110,434,117],{"class":116},[110,436,121],{"class":120},[110,438,124],{"class":116},[110,440,441],{"class":120}," QgsProject, QgsWkbTypes\n",[110,443,444,446,448,450],{"class":112,"line":130},[110,445,117],{"class":116},[110,447,135],{"class":120},[110,449,124],{"class":116},[110,451,140],{"class":120},[110,453,454],{"class":112,"line":143},[110,455,147],{"emptyLinePlaceholder":146},[110,457,458,460,462,464,467,469,471],{"class":112,"line":150},[110,459,153],{"class":120},[110,461,156],{"class":116},[110,463,159],{"class":120},[110,465,466],{"class":162},"\"features\"",[110,468,166],{"class":120},[110,470,170],{"class":169},[110,472,173],{"class":120},[110,474,475,478,480,482,484],{"class":112,"line":176},[110,476,477],{"class":120},"sl ",[110,479,156],{"class":116},[110,481,323],{"class":120},[110,483,170],{"class":169},[110,485,328],{"class":120},[110,487,488,491,493],{"class":112,"line":181},[110,489,490],{"class":120},"gtype ",[110,492,156],{"class":116},[110,494,495],{"class":120}," layer.geometryType()\n",[110,497,498],{"class":112,"line":192},[110,499,147],{"emptyLinePlaceholder":146},[110,501,502,505,508,511],{"class":112,"line":208},[110,503,504],{"class":116},"if",[110,506,507],{"class":120}," gtype ",[110,509,510],{"class":116},"==",[110,512,513],{"class":120}," QgsWkbTypes.PolygonGeometry:\n",[110,515,516,519,522,525],{"class":112,"line":213},[110,517,518],{"class":120},"    sl.setColor(QColor(",[110,520,521],{"class":162},"\"#22c55e\"",[110,523,524],{"class":120},"))          ",[110,526,527],{"class":204},"# fill\n",[110,529,530,533,536,539],{"class":112,"line":388},[110,531,532],{"class":120},"    sl.setStrokeColor(QColor(",[110,534,535],{"class":162},"\"#15803d\"",[110,537,538],{"class":120},"))    ",[110,540,541],{"class":204},"# outline\n",[110,543,544,547,549,551],{"class":112,"line":393},[110,545,546],{"class":116},"elif",[110,548,507],{"class":120},[110,550,510],{"class":116},[110,552,553],{"class":120}," QgsWkbTypes.LineGeometry:\n",[110,555,557,559,562,564],{"class":112,"line":556},12,[110,558,518],{"class":120},[110,560,561],{"class":162},"\"#2563eb\"",[110,563,524],{"class":120},[110,565,566],{"class":204},"# the line is the color\n",[110,568,570,572,574,576],{"class":112,"line":569},13,[110,571,546],{"class":116},[110,573,507],{"class":120},[110,575,510],{"class":116},[110,577,578],{"class":120}," QgsWkbTypes.PointGeometry:\n",[110,580,582,584,587,589],{"class":112,"line":581},14,[110,583,518],{"class":120},[110,585,586],{"class":162},"\"#b45309\"",[110,588,524],{"class":120},[110,590,591],{"class":204},"# marker fill\n",[110,593,595,597,600,602],{"class":112,"line":594},15,[110,596,532],{"class":120},[110,598,599],{"class":162},"\"#ffffff\"",[110,601,538],{"class":120},[110,603,604],{"class":204},"# marker outline \u002F halo\n",[110,606,608],{"class":112,"line":607},16,[110,609,147],{"emptyLinePlaceholder":146},[110,611,613],{"class":112,"line":612},17,[110,614,216],{"class":120},[14,616,617,619,620,343,623,625,626,628,629,632,633,222,635,638,639,641,642,343,645,647,648,650,651,654,655,659],{},[44,618,221],{}," For ",[44,621,622],{},"polygons",[18,624,20],{}," is the fill and ",[18,627,267],{}," is the border. For ",[44,630,631],{},"lines",", there is no fill — ",[18,634,20],{},[81,636,637],{},"is"," the stroke, and a separate ",[18,640,267],{}," does not apply. For ",[44,643,644],{},"point markers",[18,646,20],{}," fills the marker shape while ",[18,649,267],{}," outlines it. Branching on ",[18,652,653],{},"layer.geometryType()"," keeps one function working across all three layer types. Continuous, per-feature colour instead of one flat colour is the territory of data-defined overrides covered in the parent cluster, or of a full ",[27,656,658],{"href":657},"\u002Fpyqgis-cartography-visualization\u002Fgraduated-categorized-renderers\u002Fcreate-choropleth-map-pyqgis\u002F","Create a Choropleth Map in PyQGIS"," workflow when you need graduated classes.",[33,661,663],{"id":662},"recipe-4-hex-rgba-and-named-colors","Recipe 4: Hex, RGBA, and named colors",[14,665,666,668],{},[18,667,24],{}," is flexible about how you describe a colour, which matters when colours come from a config file, a web palette, or a brand guide.",[101,670,672],{"className":103,"code":671,"language":105,"meta":106,"style":106},"from qgis.PyQt.QtGui import QColor\n\nQColor(\"#2563eb\")            # 6-digit hex\nQColor(\"#882563eb\")          # 8-digit hex: alpha first (AARRGGBB)\nQColor(37, 99, 235)          # RGB integers 0-255\nQColor(37, 99, 235, 128)     # RGBA, last value is 50% alpha\nQColor(\"steelblue\")          # SVG\u002FCSS named color\n\n# Build from a config value safely:\nhex_value = \"#0f766e\"\ncolor = QColor(hex_value)\nif not color.isValid():\n    color = QColor(\"#777777\")   # fallback for a malformed string\n",[18,673,674,684,688,701,714,736,761,773,777,782,792,802,812],{"__ignoreMap":106},[110,675,676,678,680,682],{"class":112,"line":113},[110,677,117],{"class":116},[110,679,135],{"class":120},[110,681,124],{"class":116},[110,683,140],{"class":120},[110,685,686],{"class":112,"line":130},[110,687,147],{"emptyLinePlaceholder":146},[110,689,690,693,695,698],{"class":112,"line":143},[110,691,692],{"class":120},"QColor(",[110,694,561],{"class":162},[110,696,697],{"class":120},")            ",[110,699,700],{"class":204},"# 6-digit hex\n",[110,702,703,705,708,711],{"class":112,"line":150},[110,704,692],{"class":120},[110,706,707],{"class":162},"\"#882563eb\"",[110,709,710],{"class":120},")          ",[110,712,713],{"class":204},"# 8-digit hex: alpha first (AARRGGBB)\n",[110,715,716,718,721,723,726,728,731,733],{"class":112,"line":176},[110,717,692],{"class":120},[110,719,720],{"class":169},"37",[110,722,343],{"class":120},[110,724,725],{"class":169},"99",[110,727,343],{"class":120},[110,729,730],{"class":169},"235",[110,732,710],{"class":120},[110,734,735],{"class":204},"# RGB integers 0-255\n",[110,737,738,740,742,744,746,748,750,752,755,758],{"class":112,"line":181},[110,739,692],{"class":120},[110,741,720],{"class":169},[110,743,343],{"class":120},[110,745,725],{"class":169},[110,747,343],{"class":120},[110,749,730],{"class":169},[110,751,343],{"class":120},[110,753,754],{"class":169},"128",[110,756,757],{"class":120},")     ",[110,759,760],{"class":204},"# RGBA, last value is 50% alpha\n",[110,762,763,765,768,770],{"class":112,"line":192},[110,764,692],{"class":120},[110,766,767],{"class":162},"\"steelblue\"",[110,769,710],{"class":120},[110,771,772],{"class":204},"# SVG\u002FCSS named color\n",[110,774,775],{"class":112,"line":208},[110,776,147],{"emptyLinePlaceholder":146},[110,778,779],{"class":112,"line":213},[110,780,781],{"class":204},"# Build from a config value safely:\n",[110,783,784,787,789],{"class":112,"line":388},[110,785,786],{"class":120},"hex_value ",[110,788,156],{"class":116},[110,790,791],{"class":162}," \"#0f766e\"\n",[110,793,794,797,799],{"class":112,"line":393},[110,795,796],{"class":120},"color ",[110,798,156],{"class":116},[110,800,801],{"class":120}," QColor(hex_value)\n",[110,803,804,806,809],{"class":112,"line":556},[110,805,504],{"class":116},[110,807,808],{"class":116}," not",[110,810,811],{"class":120}," color.isValid():\n",[110,813,814,817,819,822,825,828],{"class":112,"line":569},[110,815,816],{"class":120},"    color ",[110,818,156],{"class":116},[110,820,821],{"class":120}," QColor(",[110,823,824],{"class":162},"\"#777777\"",[110,826,827],{"class":120},")   ",[110,829,830],{"class":204},"# fallback for a malformed string\n",[14,832,833,835,836,88,839,842,843,846,847,850,851,63],{},[44,834,221],{}," Qt's 8-digit hex puts alpha ",[81,837,838],{},"first",[18,840,841],{},"#AARRGGBB","), which trips people up; if you control the format, prefer the four-integer ",[18,844,845],{},"QColor(r, g, b, a)"," for clarity. ",[18,848,849],{},"QColor.isValid()"," lets you guard against a bad string from external input rather than silently drawing an invalid colour. Per-colour alpha set this way stacks multiplicatively with the symbol-level ",[18,852,853],{},"setOpacity()",[33,855,857],{"id":856},"recipe-5-recolor-a-categorized-layers-classes","Recipe 5: Recolor a categorized layer's classes",[14,859,860,861,864],{},"If the layer already uses a categorized renderer, ",[18,862,863],{},"renderer().symbol()"," does not exist — there is one symbol per class instead. You recolour by iterating the categories and rebuilding each one's symbol, which is a frequent need when adapting an existing thematic map to a new palette.",[101,866,868],{"className":103,"code":867,"language":105,"meta":106,"style":106},"from qgis.core import QgsProject, QgsRendererCategory\nfrom qgis.PyQt.QtGui import QColor\n\nlayer = QgsProject.instance().mapLayersByName(\"landuse\")[0]\nrenderer = layer.renderer()  # a QgsCategorizedSymbolRenderer\n\npalette = {\n    \"residential\": \"#b45309\",\n    \"commercial\": \"#2563eb\",\n    \"industrial\": \"#6b7280\",\n    \"park\": \"#22c55e\",\n}\n\nfor i, category in enumerate(renderer.categories()):\n    symbol = category.symbol().clone()\n    hex_value = palette.get(str(category.value()))\n    if hex_value:\n        symbol.setColor(QColor(hex_value))\n        renderer.updateCategorySymbol(i, symbol)\n\nlayer.triggerRepaint()\n",[18,869,870,881,891,895,912,925,929,939,952,963,975,986,991,995,1012,1022,1038,1046,1052,1058,1063],{"__ignoreMap":106},[110,871,872,874,876,878],{"class":112,"line":113},[110,873,117],{"class":116},[110,875,121],{"class":120},[110,877,124],{"class":116},[110,879,880],{"class":120}," QgsProject, QgsRendererCategory\n",[110,882,883,885,887,889],{"class":112,"line":130},[110,884,117],{"class":116},[110,886,135],{"class":120},[110,888,124],{"class":116},[110,890,140],{"class":120},[110,892,893],{"class":112,"line":143},[110,894,147],{"emptyLinePlaceholder":146},[110,896,897,899,901,903,906,908,910],{"class":112,"line":150},[110,898,153],{"class":120},[110,900,156],{"class":116},[110,902,159],{"class":120},[110,904,905],{"class":162},"\"landuse\"",[110,907,166],{"class":120},[110,909,170],{"class":169},[110,911,173],{"class":120},[110,913,914,917,919,922],{"class":112,"line":176},[110,915,916],{"class":120},"renderer ",[110,918,156],{"class":116},[110,920,921],{"class":120}," layer.renderer()  ",[110,923,924],{"class":204},"# a QgsCategorizedSymbolRenderer\n",[110,926,927],{"class":112,"line":181},[110,928,147],{"emptyLinePlaceholder":146},[110,930,931,934,936],{"class":112,"line":192},[110,932,933],{"class":120},"palette ",[110,935,156],{"class":116},[110,937,938],{"class":120}," {\n",[110,940,941,944,947,949],{"class":112,"line":208},[110,942,943],{"class":162},"    \"residential\"",[110,945,946],{"class":120},": ",[110,948,586],{"class":162},[110,950,951],{"class":120},",\n",[110,953,954,957,959,961],{"class":112,"line":213},[110,955,956],{"class":162},"    \"commercial\"",[110,958,946],{"class":120},[110,960,561],{"class":162},[110,962,951],{"class":120},[110,964,965,968,970,973],{"class":112,"line":388},[110,966,967],{"class":162},"    \"industrial\"",[110,969,946],{"class":120},[110,971,972],{"class":162},"\"#6b7280\"",[110,974,951],{"class":120},[110,976,977,980,982,984],{"class":112,"line":393},[110,978,979],{"class":162},"    \"park\"",[110,981,946],{"class":120},[110,983,521],{"class":162},[110,985,951],{"class":120},[110,987,988],{"class":112,"line":556},[110,989,990],{"class":120},"}\n",[110,992,993],{"class":112,"line":569},[110,994,147],{"emptyLinePlaceholder":146},[110,996,997,1000,1003,1006,1009],{"class":112,"line":581},[110,998,999],{"class":116},"for",[110,1001,1002],{"class":120}," i, category ",[110,1004,1005],{"class":116},"in",[110,1007,1008],{"class":169}," enumerate",[110,1010,1011],{"class":120},"(renderer.categories()):\n",[110,1013,1014,1017,1019],{"class":112,"line":594},[110,1015,1016],{"class":120},"    symbol ",[110,1018,156],{"class":116},[110,1020,1021],{"class":120}," category.symbol().clone()\n",[110,1023,1024,1027,1029,1032,1035],{"class":112,"line":607},[110,1025,1026],{"class":120},"    hex_value ",[110,1028,156],{"class":116},[110,1030,1031],{"class":120}," palette.get(",[110,1033,1034],{"class":169},"str",[110,1036,1037],{"class":120},"(category.value()))\n",[110,1039,1040,1043],{"class":112,"line":612},[110,1041,1042],{"class":116},"    if",[110,1044,1045],{"class":120}," hex_value:\n",[110,1047,1049],{"class":112,"line":1048},18,[110,1050,1051],{"class":120},"        symbol.setColor(QColor(hex_value))\n",[110,1053,1055],{"class":112,"line":1054},19,[110,1056,1057],{"class":120},"        renderer.updateCategorySymbol(i, symbol)\n",[110,1059,1061],{"class":112,"line":1060},20,[110,1062,147],{"emptyLinePlaceholder":146},[110,1064,1066],{"class":112,"line":1065},21,[110,1067,216],{"class":120},[14,1069,1070,222,1072,1075,1076,1079,1080,1083,1084,1087,1088,1090],{},[44,1071,221],{},[18,1073,1074],{},"renderer.categories()"," returns the list of ",[18,1077,1078],{},"QgsRendererCategory"," objects, each pairing a value with a symbol. You clone the existing symbol so the original is not mutated mid-iteration, recolour the clone, and write it back with ",[18,1081,1082],{},"updateCategorySymbol(index, symbol)",". Mapping ",[18,1085,1086],{},"str(category.value())"," against a dictionary keeps the colour assignment data-driven rather than positional. For building such a renderer from scratch, the ",[27,1089,658],{"href":657}," recipe is the right starting point.",[33,1092,1094],{"id":1093},"recipe-6-repaint-refresh-the-legend-and-persist","Recipe 6: Repaint, refresh the legend, and persist",[14,1096,1097],{},"The colour change is live in memory after the setter call, but three follow-ups make it visible and durable.",[101,1099,1101],{"className":103,"code":1100,"language":105,"meta":106,"style":106},"from qgis.core import QgsProject\nfrom qgis.utils import iface\n\nlayer = QgsProject.instance().mapLayersByName(\"districts\")[0]\n\n# 1. Redraw the canvas.\nlayer.triggerRepaint()\n\n# 2. Update the Layers panel swatch (skip in headless scripts).\nif iface is not None:\n    iface.layerTreeView().refreshLayerSymbology(layer.id())\n\n# 3. Save the style so it reloads with the layer next time.\nresult, message = layer.saveNamedStyle(\"\u002Fdata\u002Fdistricts.qml\")\nif not result:\n    print(f\"Style save failed: {message}\")\n",[18,1102,1103,1113,1125,1129,1145,1149,1154,1158,1162,1167,1184,1189,1193,1198,1213,1222],{"__ignoreMap":106},[110,1104,1105,1107,1109,1111],{"class":112,"line":113},[110,1106,117],{"class":116},[110,1108,121],{"class":120},[110,1110,124],{"class":116},[110,1112,127],{"class":120},[110,1114,1115,1117,1120,1122],{"class":112,"line":130},[110,1116,117],{"class":116},[110,1118,1119],{"class":120}," qgis.utils ",[110,1121,124],{"class":116},[110,1123,1124],{"class":120}," iface\n",[110,1126,1127],{"class":112,"line":143},[110,1128,147],{"emptyLinePlaceholder":146},[110,1130,1131,1133,1135,1137,1139,1141,1143],{"class":112,"line":150},[110,1132,153],{"class":120},[110,1134,156],{"class":116},[110,1136,159],{"class":120},[110,1138,163],{"class":162},[110,1140,166],{"class":120},[110,1142,170],{"class":169},[110,1144,173],{"class":120},[110,1146,1147],{"class":112,"line":176},[110,1148,147],{"emptyLinePlaceholder":146},[110,1150,1151],{"class":112,"line":181},[110,1152,1153],{"class":204},"# 1. Redraw the canvas.\n",[110,1155,1156],{"class":112,"line":192},[110,1157,216],{"class":120},[110,1159,1160],{"class":112,"line":208},[110,1161,147],{"emptyLinePlaceholder":146},[110,1163,1164],{"class":112,"line":213},[110,1165,1166],{"class":204},"# 2. Update the Layers panel swatch (skip in headless scripts).\n",[110,1168,1169,1171,1174,1176,1178,1181],{"class":112,"line":388},[110,1170,504],{"class":116},[110,1172,1173],{"class":120}," iface ",[110,1175,637],{"class":116},[110,1177,808],{"class":116},[110,1179,1180],{"class":169}," None",[110,1182,1183],{"class":120},":\n",[110,1185,1186],{"class":112,"line":393},[110,1187,1188],{"class":120},"    iface.layerTreeView().refreshLayerSymbology(layer.id())\n",[110,1190,1191],{"class":112,"line":556},[110,1192,147],{"emptyLinePlaceholder":146},[110,1194,1195],{"class":112,"line":569},[110,1196,1197],{"class":204},"# 3. Save the style so it reloads with the layer next time.\n",[110,1199,1200,1203,1205,1208,1211],{"class":112,"line":581},[110,1201,1202],{"class":120},"result, message ",[110,1204,156],{"class":116},[110,1206,1207],{"class":120}," layer.saveNamedStyle(",[110,1209,1210],{"class":162},"\"\u002Fdata\u002Fdistricts.qml\"",[110,1212,328],{"class":120},[110,1214,1215,1217,1219],{"class":112,"line":594},[110,1216,504],{"class":116},[110,1218,808],{"class":116},[110,1220,1221],{"class":120}," result:\n",[110,1223,1224,1227,1230,1233,1236,1239,1242,1245,1248],{"class":112,"line":607},[110,1225,1226],{"class":169},"    print",[110,1228,1229],{"class":120},"(",[110,1231,1232],{"class":116},"f",[110,1234,1235],{"class":162},"\"Style save failed: ",[110,1237,1238],{"class":169},"{",[110,1240,1241],{"class":120},"message",[110,1243,1244],{"class":169},"}",[110,1246,1247],{"class":162},"\"",[110,1249,328],{"class":120},[14,1251,1252,222,1254,1256,1257,1260,1261,1264,1265,1268,1269,1272,1273,63],{},[44,1253,221],{},[18,1255,250],{}," handles the map; ",[18,1258,1259],{},"refreshLayerSymbology()"," handles the legend swatch, which is a separate widget and will otherwise show the old colour. ",[18,1262,1263],{},"saveNamedStyle()"," returns a ",[18,1266,1267],{},"(success, message)"," tuple and writes a ",[18,1270,1271],{},".qml"," sidecar that QGIS loads automatically beside the data source. To embed the style inside a GeoPackage or PostGIS table instead, use ",[18,1274,1275],{},"layer.saveStyleToDatabase(\"districts\", \"auto style\", True, \"\")",[33,1277,1279],{"id":1278},"recipe-7-copy-a-color-from-one-layer-to-another","Recipe 7: Copy a color from one layer to another",[14,1281,1282],{},"To keep a set of layers visually consistent, read the colour off a reference layer and apply it to others rather than hard-coding the hex string in several places.",[101,1284,1286],{"className":103,"code":1285,"language":105,"meta":106,"style":106},"from qgis.core import QgsProject\n\nproject = QgsProject.instance()\nsource = project.mapLayersByName(\"template\")[0]\nref_color = source.renderer().symbol().color()   # a QColor\n\nfor name in (\"layer_a\", \"layer_b\", \"layer_c\"):\n    layer = project.mapLayersByName(name)[0]\n    layer.renderer().symbol().setColor(ref_color)\n    layer.triggerRepaint()\n",[18,1287,1288,1298,1302,1312,1331,1344,1348,1375,1389,1394],{"__ignoreMap":106},[110,1289,1290,1292,1294,1296],{"class":112,"line":113},[110,1291,117],{"class":116},[110,1293,121],{"class":120},[110,1295,124],{"class":116},[110,1297,127],{"class":120},[110,1299,1300],{"class":112,"line":130},[110,1301,147],{"emptyLinePlaceholder":146},[110,1303,1304,1307,1309],{"class":112,"line":143},[110,1305,1306],{"class":120},"project ",[110,1308,156],{"class":116},[110,1310,1311],{"class":120}," QgsProject.instance()\n",[110,1313,1314,1317,1319,1322,1325,1327,1329],{"class":112,"line":150},[110,1315,1316],{"class":120},"source ",[110,1318,156],{"class":116},[110,1320,1321],{"class":120}," project.mapLayersByName(",[110,1323,1324],{"class":162},"\"template\"",[110,1326,166],{"class":120},[110,1328,170],{"class":169},[110,1330,173],{"class":120},[110,1332,1333,1336,1338,1341],{"class":112,"line":176},[110,1334,1335],{"class":120},"ref_color ",[110,1337,156],{"class":116},[110,1339,1340],{"class":120}," source.renderer().symbol().color()   ",[110,1342,1343],{"class":204},"# a QColor\n",[110,1345,1346],{"class":112,"line":181},[110,1347,147],{"emptyLinePlaceholder":146},[110,1349,1350,1352,1355,1357,1359,1362,1364,1367,1369,1372],{"class":112,"line":192},[110,1351,999],{"class":116},[110,1353,1354],{"class":120}," name ",[110,1356,1005],{"class":116},[110,1358,88],{"class":120},[110,1360,1361],{"class":162},"\"layer_a\"",[110,1363,343],{"class":120},[110,1365,1366],{"class":162},"\"layer_b\"",[110,1368,343],{"class":120},[110,1370,1371],{"class":162},"\"layer_c\"",[110,1373,1374],{"class":120},"):\n",[110,1376,1377,1380,1382,1385,1387],{"class":112,"line":208},[110,1378,1379],{"class":120},"    layer ",[110,1381,156],{"class":116},[110,1383,1384],{"class":120}," project.mapLayersByName(name)[",[110,1386,170],{"class":169},[110,1388,173],{"class":120},[110,1390,1391],{"class":112,"line":213},[110,1392,1393],{"class":120},"    layer.renderer().symbol().setColor(ref_color)\n",[110,1395,1396],{"class":112,"line":388},[110,1397,1398],{"class":120},"    layer.triggerRepaint()\n",[14,1400,1401,222,1403,1406,1407,1409,1410,1412,1413,1415],{},[44,1402,221],{},[18,1404,1405],{},"symbol().color()"," reads the current symbol colour as a ",[18,1408,24],{},", which you then push into each target with ",[18,1411,20],{},". Because ",[18,1414,24],{}," is copied by value, the layers stay independent — recolouring one later does not affect the others. This is a lightweight alternative to saving and loading a full QML style when only the colour needs to match.",[33,1417,1419],{"id":1418},"qgis-version-compatibility","QGIS Version Compatibility",[14,1421,1422,1423,1426],{},"Baseline for every snippet on this page is ",[44,1424,1425],{},"QGIS 3.34 LTR with Python 3.12",". The colour and symbol-layer API has been stable across the 3.x series.",[1428,1429,1430,1446],"table",{},[1431,1432,1433],"thead",{},[1434,1435,1436,1440,1443],"tr",{},[1437,1438,1439],"th",{},"QGIS version",[1437,1441,1442],{},"Python",[1437,1444,1445],{},"Notes",[1447,1448,1449,1470,1481],"tbody",{},[1434,1450,1451,1455,1458],{},[1452,1453,1454],"td",{},"3.28 LTR",[1452,1456,1457],{},"3.9",[1452,1459,1460,343,1463,343,1466,1469],{},[18,1461,1462],{},"setColor",[18,1464,1465],{},"setStrokeColor",[18,1467,1468],{},"saveNamedStyle"," all present and identical.",[1434,1471,1472,1475,1478],{},[1452,1473,1474],{},"3.34 LTR",[1452,1476,1477],{},"3.12",[1452,1479,1480],{},"Reference version; run as written.",[1434,1482,1483,1486,1488],{},[1452,1484,1485],{},"3.40 \u002F 3.44",[1452,1487,1477],{},[1452,1489,1490,1493,1494,1497],{},[18,1491,1492],{},"QgsWkbTypes.PolygonGeometry"," etc. still resolve; scoped forms like ",[18,1495,1496],{},"Qgis.GeometryType.Polygon"," are the newer preferred spelling.",[14,1499,1500],{},"If you target both 3.28 and the 3.40+ line from one script, stick to the flat enum names shown here — they remain valid everywhere.",[33,1502,1504],{"id":1503},"troubleshooting","Troubleshooting",[14,1506,1507,1512,1513,1515,1516,1518,1519,1522,1523,63],{},[44,1508,1509],{},[18,1510,1511],{},"AttributeError: 'QgsCategorizedSymbolRenderer' object has no attribute 'symbol'","\nThe layer is not using a single-symbol renderer. ",[18,1514,863],{}," only exists on ",[18,1517,229],{},". Either reset the layer with ",[18,1520,1521],{},"QgsSingleSymbolRenderer(QgsSymbol.defaultSymbol(layer.geometryType()))"," first, or, for a categorized layer, recolour an individual class via ",[18,1524,1525],{},"renderer().symbols(QgsRenderContext())",[14,1527,1528,1531,1532,1534,1535,1537,1538,63],{},[44,1529,1530],{},"The canvas updated but the legend still shows the old color.","\nYou called ",[18,1533,250],{}," but not ",[18,1536,1259],{},". Add ",[18,1539,1540],{},"iface.layerTreeView().refreshLayerSymbology(layer.id())",[14,1542,1543,1546,1547,1549,1550,1552,1553,1556],{},[44,1544,1545],{},"The color reverts after reopening the project.","\nThe change lived only in memory. Call ",[18,1548,1263],{}," to write a ",[18,1551,1271],{},", or save the QGIS project so the styling is stored in the ",[18,1554,1555],{},".qgz"," file.",[14,1558,1559,1564,1565,1567,1568,1571],{},[44,1560,1561,1563],{},[18,1562,1465],{}," did nothing on a line layer.","\nLine symbol layers have no separate stroke — the line itself is the stroke. Use ",[18,1566,20],{}," to recolour a line and ",[18,1569,1570],{},"setWidth()"," to size it.",[14,1573,1574,1577,1578,1580,1581,1584,1585,1587],{},[44,1575,1576],{},"The colour looks too dark or fully opaque despite an alpha value.","\nCheck whether you used the 8-digit hex form, where alpha comes first (",[18,1579,841],{},"). A value like ",[18,1582,1583],{},"#ff2563eb"," is fully opaque blue, not 100% of something else. Prefer ",[18,1586,845],{}," to avoid ambiguity.",[33,1589,1591],{"id":1590},"conclusion","Conclusion",[14,1593,1594,1595,1597,1598,1600,1601,1603,1604,1606],{},"Setting a vector layer's colour comes down to three decisions: which object to target (the symbol for a flat recolour, the symbol layer for separate fill and outline), how to express the colour (hex, RGBA, or a named colour via ",[18,1596,24],{},"), and how to make it stick (",[18,1599,250],{}," plus ",[18,1602,1259],{},", then ",[18,1605,1263],{},"). With those in hand you can recolour any single-symbol layer reliably across QGIS versions. When you need colour to vary by value rather than a single flat fill, move on to a color ramp or a graduated renderer.",[33,1608,1610],{"id":1609},"frequently-asked-questions","Frequently Asked Questions",[14,1612,1613,1616,1617,946,1619,1603,1622,1624,1625,1627],{},[44,1614,1615],{},"How do I set only the outline color and leave the fill alone?","\nTarget the symbol layer and call only ",[18,1618,267],{},[18,1620,1621],{},"layer.renderer().symbol().symbolLayer(0).setStrokeColor(QColor(\"#000000\"))",[18,1623,250],{},". Do not call ",[18,1626,20],{},", which would change the fill.",[14,1629,1630,1633,1634,1637,1638,1641],{},[44,1631,1632],{},"Can I use a hex string directly without converting it?","\nYes. ",[18,1635,1636],{},"QColor(\"#2563eb\")"," accepts a hex string. Guard external input with ",[18,1639,1640],{},"QColor(value).isValid()"," so a malformed string does not silently produce an invalid colour.",[14,1643,1644,1650,1651,1653,1654,63],{},[44,1645,1646,1647,1649],{},"Why does the same ",[18,1648,20],{}," change the fill on polygons but the line on lines?","\nBecause the symbol-layer classes differ. A line has no fill, so its primary colour ",[81,1652,637],{}," the stroke; on a polygon the primary colour is the fill and the outline is a separate ",[18,1655,267],{},[14,1657,1658,1661,1662,1665,1666,1669],{},[44,1659,1660],{},"How do I make the colour change permanent?","\nEither save the QGIS project, or call ",[18,1663,1664],{},"layer.saveNamedStyle(\"path.qml\")"," to write a sidecar that loads with the data source. For database-backed layers, ",[18,1667,1668],{},"saveStyleToDatabase()"," stores the style in the GeoPackage or PostGIS table.",[33,1671,1673],{"id":1672},"related","Related",[38,1675,1676,1680,1686],{},[41,1677,1678],{},[27,1679,30],{"href":29},[41,1681,1682],{},[27,1683,1685],{"href":1684},"\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fapply-color-ramp-to-raster-pyqgis\u002F","Apply a Color Ramp to a Raster in PyQGIS",[41,1687,1688],{},[27,1689,658],{"href":657},[1691,1692,1693],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":106,"searchDepth":130,"depth":130,"links":1695},[1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709],{"id":35,"depth":130,"text":36},{"id":69,"depth":130,"text":70},{"id":95,"depth":130,"text":96},{"id":254,"depth":130,"text":255},{"id":421,"depth":130,"text":422},{"id":662,"depth":130,"text":663},{"id":856,"depth":130,"text":857},{"id":1093,"depth":130,"text":1094},{"id":1278,"depth":130,"text":1279},{"id":1418,"depth":130,"text":1419},{"id":1503,"depth":130,"text":1504},{"id":1590,"depth":130,"text":1591},{"id":1609,"depth":130,"text":1610},{"id":1672,"depth":130,"text":1673},"Change a vector layer's symbol color and outline in PyQGIS with setColor, setStrokeColor, and QColor, then trigger a repaint, refresh the legend, and save.","md",{},"\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fset-vector-layer-symbol-color-pyqgis",{"title":5,"description":1710},"pyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fset-vector-layer-symbol-color-pyqgis\u002Findex","mh_2KOt2W3RN4bCPnWHbxT2Qc_EUTrZT92v5Z7KAW3I",1781792483473]