[{"data":1,"prerenderedAt":1830},["ShallowReactive",2],{"doc:\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-stacked-bar-diagrams-pyqgis":3},{"id":4,"title":5,"body":6,"description":1819,"extension":1820,"meta":1821,"navigation":226,"path":1826,"seo":1827,"stem":1828,"__hash__":1829},"docs\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-stacked-bar-diagrams-pyqgis\u002Findex.md","Add Stacked Bar Diagrams in PyQGIS",{"type":7,"value":8,"toc":1804},"minimark",[9,13,17,26,130,135,154,158,161,548,567,571,574,652,850,855,859,862,950,959,963,966,1114,1119,1123,1126,1331,1345,1349,1355,1455,1655,1664,1668,1671,1675,1686,1690,1724,1728,1737,1741,1747,1753,1759,1765,1769,1800],[10,11,5],"h1",{"id":12},"add-stacked-bar-diagrams-in-pyqgis",[14,15,16],"p",{},"Pies show composition but not size; bar charts show size but make the whole hard to see. A stacked bar does both: one bar per feature whose length is the total, divided into segments for each part. Housing stock by tenure, energy use by source, waste by stream — whenever readers need to see both \"how much\" and \"made of what\", a stacked bar diagram is usually the clearest choice that QGIS can draw on a map.",[14,18,19,20,25],{},"This recipe belongs to ",[21,22,24],"a",{"href":23},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002F","Diagrams & Charts on Maps",". It builds a stacked bar diagram renderer, orders and colours segments, scales bar length by the total, switches to 100 % bars when only composition matters, and shows how QGIS 3.40's stacked diagram combines several diagram types on one feature.",[14,27,28],{},[29,30,35,39,43,50,59,67,76,80,85,89,93,97,101,105,109,113,117,123,126],"svg",{"viewBox":31,"role":32,"ariaLabel":33,"xmlns":34},"0 0 760 258","img","Three stacked bars showing total dwellings by length and tenure composition by segments, comparable in both respects","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[36,37,38],"title",{},"One bar, total and parts",[40,41,42],"desc",{},"Three districts each with a single stacked bar. Bar length is the total number of dwellings. Each bar is divided into segments for owner occupied, private rented and social rented. A long bar with a large social segment and a short bar with a large private segment can be compared in total and in composition at once.",[44,45],"rect",{"x":46,"y":46,"width":47,"height":48,"fill":49},"0","760","258","#f6f3ea",[51,52,58],"text",{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"380","28","text-anchor:middle;font-size:14px;font-family:sans-serif;font-weight:bold","#17211d","middle","Length is the total, segments are the parts",[51,60,66],{"x":61,"y":62,"style":63,"fill":64,"textAnchor":65},"120","92","text-anchor:end;font-size:11.0px;font-family:sans-serif","#2f3b35","end","North",[44,68],{"x":69,"y":70,"width":71,"height":72,"rx":46,"fill":73,"stroke":74,"style":75},"130","78","260","22","#0f766e","#fffdf7","stroke-width:1",[44,77],{"x":78,"y":70,"width":61,"height":72,"rx":46,"fill":79,"stroke":74,"style":75},"390","#2563eb",[44,81],{"x":82,"y":70,"width":83,"height":72,"rx":46,"fill":84,"stroke":74,"style":75},"510","160","#b45309",[51,86,88],{"x":61,"y":87,"style":63,"fill":64,"textAnchor":65},"142","Centre",[44,90],{"x":69,"y":91,"width":92,"height":72,"rx":46,"fill":73,"stroke":74,"style":75},"128","90",[44,94],{"x":95,"y":91,"width":96,"height":72,"rx":46,"fill":79,"stroke":74,"style":75},"220","190",[44,98],{"x":99,"y":91,"width":100,"height":72,"rx":46,"fill":84,"stroke":74,"style":75},"410","40",[51,102,104],{"x":61,"y":103,"style":63,"fill":64,"textAnchor":65},"192","East",[44,106],{"x":69,"y":107,"width":108,"height":72,"rx":46,"fill":73,"stroke":74,"style":75},"178","150",[44,110],{"x":111,"y":107,"width":112,"height":72,"rx":46,"fill":79,"stroke":74,"style":75},"280","60",[44,114],{"x":115,"y":107,"width":116,"height":72,"rx":46,"fill":84,"stroke":74,"style":75},"340","80",[51,118,122],{"x":119,"y":120,"style":121,"fill":73,"textAnchor":57},"200","238","text-anchor:middle;font-size:10.5px;font-family:sans-serif","owner occupied",[51,124,125],{"x":53,"y":120,"style":121,"fill":79,"textAnchor":57},"private rented",[51,127,129],{"x":128,"y":120,"style":121,"fill":84,"textAnchor":57},"560","social rented",[131,132,134],"h2",{"id":133},"prerequisites","Prerequisites",[136,137,138,151],"ul",{},[139,140,141,142,146,147,150],"li",{},"QGIS 3.34 LTR or newer for ",[143,144,145],"code",{},"QgsStackedBarDiagram"," (available since 3.12); 3.40 or newer for the combined ",[143,148,149],{},"QgsStackedDiagram",".",[139,152,153],{},"A layer with numeric fields that are additive parts of a total, all in the same unit.",[131,155,157],{"id":156},"build-a-stacked-bar-diagram","Build a stacked bar diagram",[14,159,160],{},"The setup mirrors other diagram types. With a single-category renderer every bar has the same length, which shows composition only; the next section scales length by the total.",[162,163,168],"pre",{"className":164,"code":165,"language":166,"meta":167,"style":167},"language-python shiki shiki-themes github-dark","from qgis.core import (QgsProject, QgsStackedBarDiagram, QgsDiagramSettings,\n                       QgsSingleCategoryDiagramRenderer, QgsDiagramLayerSettings)\nfrom qgis.PyQt.QtGui import QColor\nfrom qgis.PyQt.QtCore import QSizeF\n\nwards = QgsProject.instance().mapLayersByName(\"wards\")[0]\nparts = [(\"owner_occ\", \"owner occupied\", \"#0f766e\"),\n         (\"private_rent\", \"private rented\", \"#2563eb\"),\n         (\"social_rent\", \"social rented\", \"#b45309\")]\n\nsettings = QgsDiagramSettings()\nsettings.categoryAttributes = [f'coalesce(\"{f}\", 0)' for f, _, _ in parts]\nsettings.categoryLabels = [label for _, label, _ in parts]\nsettings.categoryColors = [QColor(c) for _, _, c in parts]\nsettings.diagramOrientation = QgsDiagramSettings.Right\nsettings.barWidth = 2.5\nsettings.size = QSizeF(20, 2.5)\nsettings.penColor = QColor(\"#ffffff\")\nsettings.penWidth = 0.2\nsettings.enabled = True\n\nrenderer = QgsSingleCategoryDiagramRenderer()\nrenderer.setDiagram(QgsStackedBarDiagram())\nrenderer.setDiagramSettings(settings)\nwards.setDiagramRenderer(renderer)\nwards.setDiagramLayerSettings(QgsDiagramLayerSettings())\nwards.triggerRepaint()\n","python","",[143,169,170,189,195,208,221,228,253,281,302,323,328,339,379,400,420,431,442,464,480,491,502,507,518,524,530,536,542],{"__ignoreMap":167},[171,172,175,179,183,186],"span",{"class":173,"line":174},"line",1,[171,176,178],{"class":177},"snl16","from",[171,180,182],{"class":181},"s95oV"," qgis.core ",[171,184,185],{"class":177},"import",[171,187,188],{"class":181}," (QgsProject, QgsStackedBarDiagram, QgsDiagramSettings,\n",[171,190,192],{"class":173,"line":191},2,[171,193,194],{"class":181},"                       QgsSingleCategoryDiagramRenderer, QgsDiagramLayerSettings)\n",[171,196,198,200,203,205],{"class":173,"line":197},3,[171,199,178],{"class":177},[171,201,202],{"class":181}," qgis.PyQt.QtGui ",[171,204,185],{"class":177},[171,206,207],{"class":181}," QColor\n",[171,209,211,213,216,218],{"class":173,"line":210},4,[171,212,178],{"class":177},[171,214,215],{"class":181}," qgis.PyQt.QtCore ",[171,217,185],{"class":177},[171,219,220],{"class":181}," QSizeF\n",[171,222,224],{"class":173,"line":223},5,[171,225,227],{"emptyLinePlaceholder":226},true,"\n",[171,229,231,234,237,240,244,247,250],{"class":173,"line":230},6,[171,232,233],{"class":181},"wards ",[171,235,236],{"class":177},"=",[171,238,239],{"class":181}," QgsProject.instance().mapLayersByName(",[171,241,243],{"class":242},"sU2Wk","\"wards\"",[171,245,246],{"class":181},")[",[171,248,46],{"class":249},"sDLfK",[171,251,252],{"class":181},"]\n",[171,254,256,259,261,264,267,270,273,275,278],{"class":173,"line":255},7,[171,257,258],{"class":181},"parts ",[171,260,236],{"class":177},[171,262,263],{"class":181}," [(",[171,265,266],{"class":242},"\"owner_occ\"",[171,268,269],{"class":181},", ",[171,271,272],{"class":242},"\"owner occupied\"",[171,274,269],{"class":181},[171,276,277],{"class":242},"\"#0f766e\"",[171,279,280],{"class":181},"),\n",[171,282,284,287,290,292,295,297,300],{"class":173,"line":283},8,[171,285,286],{"class":181},"         (",[171,288,289],{"class":242},"\"private_rent\"",[171,291,269],{"class":181},[171,293,294],{"class":242},"\"private rented\"",[171,296,269],{"class":181},[171,298,299],{"class":242},"\"#2563eb\"",[171,301,280],{"class":181},[171,303,305,307,310,312,315,317,320],{"class":173,"line":304},9,[171,306,286],{"class":181},[171,308,309],{"class":242},"\"social_rent\"",[171,311,269],{"class":181},[171,313,314],{"class":242},"\"social rented\"",[171,316,269],{"class":181},[171,318,319],{"class":242},"\"#b45309\"",[171,321,322],{"class":181},")]\n",[171,324,326],{"class":173,"line":325},10,[171,327,227],{"emptyLinePlaceholder":226},[171,329,331,334,336],{"class":173,"line":330},11,[171,332,333],{"class":181},"settings ",[171,335,236],{"class":177},[171,337,338],{"class":181}," QgsDiagramSettings()\n",[171,340,342,345,347,350,353,356,359,361,364,367,370,373,376],{"class":173,"line":341},12,[171,343,344],{"class":181},"settings.categoryAttributes ",[171,346,236],{"class":177},[171,348,349],{"class":181}," [",[171,351,352],{"class":177},"f",[171,354,355],{"class":242},"'coalesce(\"",[171,357,358],{"class":249},"{",[171,360,352],{"class":181},[171,362,363],{"class":249},"}",[171,365,366],{"class":242},"\", 0)'",[171,368,369],{"class":177}," for",[171,371,372],{"class":181}," f, _, _ ",[171,374,375],{"class":177},"in",[171,377,378],{"class":181}," parts]\n",[171,380,382,385,387,390,393,396,398],{"class":173,"line":381},13,[171,383,384],{"class":181},"settings.categoryLabels ",[171,386,236],{"class":177},[171,388,389],{"class":181}," [label ",[171,391,392],{"class":177},"for",[171,394,395],{"class":181}," _, label, _ ",[171,397,375],{"class":177},[171,399,378],{"class":181},[171,401,403,406,408,411,413,416,418],{"class":173,"line":402},14,[171,404,405],{"class":181},"settings.categoryColors ",[171,407,236],{"class":177},[171,409,410],{"class":181}," [QColor(c) ",[171,412,392],{"class":177},[171,414,415],{"class":181}," _, _, c ",[171,417,375],{"class":177},[171,419,378],{"class":181},[171,421,423,426,428],{"class":173,"line":422},15,[171,424,425],{"class":181},"settings.diagramOrientation ",[171,427,236],{"class":177},[171,429,430],{"class":181}," QgsDiagramSettings.Right\n",[171,432,434,437,439],{"class":173,"line":433},16,[171,435,436],{"class":181},"settings.barWidth ",[171,438,236],{"class":177},[171,440,441],{"class":249}," 2.5\n",[171,443,445,448,450,453,456,458,461],{"class":173,"line":444},17,[171,446,447],{"class":181},"settings.size ",[171,449,236],{"class":177},[171,451,452],{"class":181}," QSizeF(",[171,454,455],{"class":249},"20",[171,457,269],{"class":181},[171,459,460],{"class":249},"2.5",[171,462,463],{"class":181},")\n",[171,465,467,470,472,475,478],{"class":173,"line":466},18,[171,468,469],{"class":181},"settings.penColor ",[171,471,236],{"class":177},[171,473,474],{"class":181}," QColor(",[171,476,477],{"class":242},"\"#ffffff\"",[171,479,463],{"class":181},[171,481,483,486,488],{"class":173,"line":482},19,[171,484,485],{"class":181},"settings.penWidth ",[171,487,236],{"class":177},[171,489,490],{"class":249}," 0.2\n",[171,492,494,497,499],{"class":173,"line":493},20,[171,495,496],{"class":181},"settings.enabled ",[171,498,236],{"class":177},[171,500,501],{"class":249}," True\n",[171,503,505],{"class":173,"line":504},21,[171,506,227],{"emptyLinePlaceholder":226},[171,508,510,513,515],{"class":173,"line":509},22,[171,511,512],{"class":181},"renderer ",[171,514,236],{"class":177},[171,516,517],{"class":181}," QgsSingleCategoryDiagramRenderer()\n",[171,519,521],{"class":173,"line":520},23,[171,522,523],{"class":181},"renderer.setDiagram(QgsStackedBarDiagram())\n",[171,525,527],{"class":173,"line":526},24,[171,528,529],{"class":181},"renderer.setDiagramSettings(settings)\n",[171,531,533],{"class":173,"line":532},25,[171,534,535],{"class":181},"wards.setDiagramRenderer(renderer)\n",[171,537,539],{"class":173,"line":538},26,[171,540,541],{"class":181},"wards.setDiagramLayerSettings(QgsDiagramLayerSettings())\n",[171,543,545],{"class":173,"line":544},27,[171,546,547],{"class":181},"wards.triggerRepaint()\n",[14,549,550,554,555,558,559,562,563,566],{},[551,552,553],"strong",{},"Breakdown:"," ",[143,556,557],{},"coalesce"," keeps a NULL part from removing the whole bar, since expression arithmetic with NULL gives NULL. A horizontal orientation (",[143,560,561],{},"Right",") suits stacked bars on maps because labels and features are usually wider than tall and horizontal bars sit comfortably under a place name. The bar width is the thickness of the bar; with a fixed-size renderer, ",[143,564,565],{},"size"," sets the full bar length. White separators between segments keep adjacent colours distinct.",[131,568,570],{"id":569},"scale-bar-length-by-the-total","Scale bar length by the total",[14,572,573],{},"With the linearly interpolated renderer, bar length follows the sum of the parts, so the diagram shows magnitude as well as composition.",[14,575,576],{},[29,577,580,583,586,589,592,599,603,606,609,613,616,620,625,628,631,634,637,639,643,647],{"viewBox":578,"role":32,"ariaLabel":579,"xmlns":34},"0 0 760 218","Stacked bars at a fixed length showing only composition, compared with bars scaled to their totals showing both magnitude and composition",[36,581,582],{},"Fixed length versus scaled length",[40,584,585],{},"Left: every bar has the same length, so only composition is visible and a small ward looks as important as a large one. Right: bar length is interpolated from zero to the largest total, so a ward with twice the dwellings has a bar twice as long, while segments still show the tenure mix.",[44,587],{"x":46,"y":46,"width":47,"height":588,"fill":49},"218",[51,590,591],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Same composition, now with magnitude",[44,593],{"x":594,"y":595,"width":115,"height":108,"rx":596,"fill":74,"stroke":597,"style":598},"24","52","8","#59645f","stroke-width:1.5",[44,600],{"x":112,"y":601,"width":61,"height":602,"rx":46,"fill":73,"stroke":74,"style":75},"86","18",[44,604],{"x":605,"y":601,"width":112,"height":602,"rx":46,"fill":79,"stroke":74,"style":75},"180",[44,607],{"x":608,"y":601,"width":116,"height":602,"rx":46,"fill":84,"stroke":74,"style":75},"240",[44,610],{"x":112,"y":611,"width":612,"height":602,"rx":46,"fill":73,"stroke":74,"style":75},"140","50",[44,614],{"x":615,"y":611,"width":611,"height":602,"rx":46,"fill":79,"stroke":74,"style":75},"110",[44,617],{"x":618,"y":611,"width":619,"height":602,"rx":46,"fill":84,"stroke":74,"style":75},"250","70",[51,621,624],{"x":622,"y":623,"style":121,"fill":597,"textAnchor":57},"194","186","fixed: composition only",[44,626],{"x":627,"y":595,"width":115,"height":108,"rx":596,"fill":74,"stroke":597,"style":598},"396",[44,629],{"x":630,"y":601,"width":61,"height":602,"rx":46,"fill":73,"stroke":74,"style":75},"432",[44,632],{"x":633,"y":601,"width":112,"height":602,"rx":46,"fill":79,"stroke":74,"style":75},"552",[44,635],{"x":636,"y":601,"width":116,"height":602,"rx":46,"fill":84,"stroke":74,"style":75},"612",[44,638],{"x":630,"y":611,"width":72,"height":602,"rx":46,"fill":73,"stroke":74,"style":75},[44,640],{"x":641,"y":611,"width":642,"height":602,"rx":46,"fill":79,"stroke":74,"style":75},"454","62",[44,644],{"x":645,"y":611,"width":646,"height":602,"rx":46,"fill":84,"stroke":74,"style":75},"516","30",[51,648,651],{"x":649,"y":623,"style":121,"fill":650,"textAnchor":57},"566","#166534","scaled: total and composition",[162,653,655],{"className":164,"code":654,"language":166,"meta":167,"style":167},"from qgis.core import QgsLinearlyInterpolatedDiagramRenderer\n\ntotal_expr = \" + \".join(f'coalesce(\"{f}\", 0)' for f, _, _ in parts)\nmax_total = max(sum((feat[f] or 0) for f, _, _ in parts) for feat in wards.getFeatures())\n\nscaled = QgsLinearlyInterpolatedDiagramRenderer()\nscaled.setDiagram(QgsStackedBarDiagram())\nscaled.setDiagramSettings(settings)\nscaled.setClassificationAttributeExpression(total_expr)\nscaled.setLowerValue(0)\nscaled.setUpperValue(max_total)\nscaled.setLowerSize(QSizeF(0, 2.5))\nscaled.setUpperSize(QSizeF(24, 2.5))\nwards.setDiagramRenderer(scaled)\nwards.triggerRepaint()\nprint(\"longest bar =\", max_total, \"dwellings\")\n",[143,656,657,668,672,706,753,757,767,772,777,782,791,796,810,823,828,832],{"__ignoreMap":167},[171,658,659,661,663,665],{"class":173,"line":174},[171,660,178],{"class":177},[171,662,182],{"class":181},[171,664,185],{"class":177},[171,666,667],{"class":181}," QgsLinearlyInterpolatedDiagramRenderer\n",[171,669,670],{"class":173,"line":191},[171,671,227],{"emptyLinePlaceholder":226},[171,673,674,677,679,682,685,687,689,691,693,695,697,699,701,703],{"class":173,"line":197},[171,675,676],{"class":181},"total_expr ",[171,678,236],{"class":177},[171,680,681],{"class":242}," \" + \"",[171,683,684],{"class":181},".join(",[171,686,352],{"class":177},[171,688,355],{"class":242},[171,690,358],{"class":249},[171,692,352],{"class":181},[171,694,363],{"class":249},[171,696,366],{"class":242},[171,698,369],{"class":177},[171,700,372],{"class":181},[171,702,375],{"class":177},[171,704,705],{"class":181}," parts)\n",[171,707,708,711,713,716,719,722,725,728,731,734,736,738,740,743,745,748,750],{"class":173,"line":210},[171,709,710],{"class":181},"max_total ",[171,712,236],{"class":177},[171,714,715],{"class":249}," max",[171,717,718],{"class":181},"(",[171,720,721],{"class":249},"sum",[171,723,724],{"class":181},"((feat[f] ",[171,726,727],{"class":177},"or",[171,729,730],{"class":249}," 0",[171,732,733],{"class":181},") ",[171,735,392],{"class":177},[171,737,372],{"class":181},[171,739,375],{"class":177},[171,741,742],{"class":181}," parts) ",[171,744,392],{"class":177},[171,746,747],{"class":181}," feat ",[171,749,375],{"class":177},[171,751,752],{"class":181}," wards.getFeatures())\n",[171,754,755],{"class":173,"line":223},[171,756,227],{"emptyLinePlaceholder":226},[171,758,759,762,764],{"class":173,"line":230},[171,760,761],{"class":181},"scaled ",[171,763,236],{"class":177},[171,765,766],{"class":181}," QgsLinearlyInterpolatedDiagramRenderer()\n",[171,768,769],{"class":173,"line":255},[171,770,771],{"class":181},"scaled.setDiagram(QgsStackedBarDiagram())\n",[171,773,774],{"class":173,"line":283},[171,775,776],{"class":181},"scaled.setDiagramSettings(settings)\n",[171,778,779],{"class":173,"line":304},[171,780,781],{"class":181},"scaled.setClassificationAttributeExpression(total_expr)\n",[171,783,784,787,789],{"class":173,"line":325},[171,785,786],{"class":181},"scaled.setLowerValue(",[171,788,46],{"class":249},[171,790,463],{"class":181},[171,792,793],{"class":173,"line":330},[171,794,795],{"class":181},"scaled.setUpperValue(max_total)\n",[171,797,798,801,803,805,807],{"class":173,"line":341},[171,799,800],{"class":181},"scaled.setLowerSize(QSizeF(",[171,802,46],{"class":249},[171,804,269],{"class":181},[171,806,460],{"class":249},[171,808,809],{"class":181},"))\n",[171,811,812,815,817,819,821],{"class":173,"line":381},[171,813,814],{"class":181},"scaled.setUpperSize(QSizeF(",[171,816,594],{"class":249},[171,818,269],{"class":181},[171,820,460],{"class":249},[171,822,809],{"class":181},[171,824,825],{"class":173,"line":402},[171,826,827],{"class":181},"wards.setDiagramRenderer(scaled)\n",[171,829,830],{"class":173,"line":422},[171,831,547],{"class":181},[171,833,834,837,839,842,845,848],{"class":173,"line":433},[171,835,836],{"class":249},"print",[171,838,718],{"class":181},[171,840,841],{"class":242},"\"longest bar =\"",[171,843,844],{"class":181},", max_total, ",[171,846,847],{"class":242},"\"dwellings\"",[171,849,463],{"class":181},[14,851,852,854],{},[551,853,553],{}," The classification expression is the total, and the interpolation maps zero to zero length and the largest total to 24 mm. Width (the bar's thickness) stays fixed at 2.5 mm through the size pairs — only the length changes. Starting at zero keeps lengths proportional, which is what makes bars comparable; a non-zero lower value would exaggerate differences. Use the same upper value on every map in a series so bars remain comparable between maps.",[131,856,858],{"id":857},"percentage-bars-for-pure-composition","Percentage bars for pure composition",[14,860,861],{},"When totals differ wildly — a city ward and a rural ward — scaled bars make the small ward's composition unreadable. Bars of equal length showing percentages put the focus entirely on composition.",[162,863,865],{"className":164,"code":864,"language":166,"meta":167,"style":167},"shares = [f'100 * coalesce(\"{f}\", 0) \u002F nullif({total_expr}, 0)' for f, _, _ in parts]\nsettings.categoryAttributes = shares\nsettings.size = QSizeF(20, 2.5)\nrenderer.setDiagramSettings(settings)\nwards.setDiagramRenderer(renderer)       # the fixed-size renderer from above\nwards.triggerRepaint()\n",[143,866,867,908,917,933,937,946],{"__ignoreMap":167},[171,868,869,872,874,876,878,881,883,885,887,890,892,895,897,900,902,904,906],{"class":173,"line":174},[171,870,871],{"class":181},"shares ",[171,873,236],{"class":177},[171,875,349],{"class":181},[171,877,352],{"class":177},[171,879,880],{"class":242},"'100 * coalesce(\"",[171,882,358],{"class":249},[171,884,352],{"class":181},[171,886,363],{"class":249},[171,888,889],{"class":242},"\", 0) \u002F nullif(",[171,891,358],{"class":249},[171,893,894],{"class":181},"total_expr",[171,896,363],{"class":249},[171,898,899],{"class":242},", 0)'",[171,901,369],{"class":177},[171,903,372],{"class":181},[171,905,375],{"class":177},[171,907,378],{"class":181},[171,909,910,912,914],{"class":173,"line":191},[171,911,344],{"class":181},[171,913,236],{"class":177},[171,915,916],{"class":181}," shares\n",[171,918,919,921,923,925,927,929,931],{"class":173,"line":197},[171,920,447],{"class":181},[171,922,236],{"class":177},[171,924,452],{"class":181},[171,926,455],{"class":249},[171,928,269],{"class":181},[171,930,460],{"class":249},[171,932,463],{"class":181},[171,934,935],{"class":173,"line":210},[171,936,529],{"class":181},[171,938,939,942],{"class":173,"line":223},[171,940,941],{"class":181},"wards.setDiagramRenderer(renderer)       ",[171,943,945],{"class":944},"sjoCn","# the fixed-size renderer from above\n",[171,947,948],{"class":173,"line":230},[171,949,547],{"class":181},[14,951,952,954,955,958],{},[551,953,553],{}," Each segment's expression computes its percentage of the ward total; ",[143,956,957],{},"nullif"," turns a zero total into NULL, so empty wards produce no bar instead of a division error. With the fixed-size renderer every bar is 20 mm long and segments show shares directly — the map equivalent of a 100 % stacked bar chart. Pair this map with a separate choropleth or proportional symbol map of totals if magnitude still matters.",[131,960,962],{"id":961},"choose-segment-order-and-colours","Choose segment order and colours",[14,964,965],{},"Segment order is the same in every bar. Putting the category of most interest at the start — the left end of horizontal bars — gives it a common baseline, so it can be compared precisely across features; segments in the middle float and are harder to compare.",[162,967,969],{"className":164,"code":968,"language":166,"meta":167,"style":167},"focus = \"social_rent\"\nordered = [p for p in parts if p[0] == focus] + [p for p in parts if p[0] != focus]\nsettings.categoryAttributes = [f'coalesce(\"{f}\", 0)' for f, _, _ in ordered]\nsettings.categoryLabels = [label for _, label, _ in ordered]\nsettings.categoryColors = [QColor(c) for _, _, c in ordered]\nscaled.setDiagramSettings(settings)\nwards.triggerRepaint()\n",[143,970,971,981,1045,1074,1090,1106,1110],{"__ignoreMap":167},[171,972,973,976,978],{"class":173,"line":174},[171,974,975],{"class":181},"focus ",[171,977,236],{"class":177},[171,979,980],{"class":242}," \"social_rent\"\n",[171,982,983,986,988,991,993,996,998,1001,1004,1007,1009,1012,1015,1018,1021,1023,1025,1027,1029,1031,1033,1035,1037,1039,1042],{"class":173,"line":191},[171,984,985],{"class":181},"ordered ",[171,987,236],{"class":177},[171,989,990],{"class":181}," [p ",[171,992,392],{"class":177},[171,994,995],{"class":181}," p ",[171,997,375],{"class":177},[171,999,1000],{"class":181}," parts ",[171,1002,1003],{"class":177},"if",[171,1005,1006],{"class":181}," p[",[171,1008,46],{"class":249},[171,1010,1011],{"class":181},"] ",[171,1013,1014],{"class":177},"==",[171,1016,1017],{"class":181}," focus] ",[171,1019,1020],{"class":177},"+",[171,1022,990],{"class":181},[171,1024,392],{"class":177},[171,1026,995],{"class":181},[171,1028,375],{"class":177},[171,1030,1000],{"class":181},[171,1032,1003],{"class":177},[171,1034,1006],{"class":181},[171,1036,46],{"class":249},[171,1038,1011],{"class":181},[171,1040,1041],{"class":177},"!=",[171,1043,1044],{"class":181}," focus]\n",[171,1046,1047,1049,1051,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071],{"class":173,"line":197},[171,1048,344],{"class":181},[171,1050,236],{"class":177},[171,1052,349],{"class":181},[171,1054,352],{"class":177},[171,1056,355],{"class":242},[171,1058,358],{"class":249},[171,1060,352],{"class":181},[171,1062,363],{"class":249},[171,1064,366],{"class":242},[171,1066,369],{"class":177},[171,1068,372],{"class":181},[171,1070,375],{"class":177},[171,1072,1073],{"class":181}," ordered]\n",[171,1075,1076,1078,1080,1082,1084,1086,1088],{"class":173,"line":210},[171,1077,384],{"class":181},[171,1079,236],{"class":177},[171,1081,389],{"class":181},[171,1083,392],{"class":177},[171,1085,395],{"class":181},[171,1087,375],{"class":177},[171,1089,1073],{"class":181},[171,1091,1092,1094,1096,1098,1100,1102,1104],{"class":173,"line":223},[171,1093,405],{"class":181},[171,1095,236],{"class":177},[171,1097,410],{"class":181},[171,1099,392],{"class":177},[171,1101,415],{"class":181},[171,1103,375],{"class":177},[171,1105,1073],{"class":181},[171,1107,1108],{"class":173,"line":230},[171,1109,776],{"class":181},[171,1111,1112],{"class":173,"line":255},[171,1113,547],{"class":181},[14,1115,1116,1118],{},[551,1117,553],{}," Only the first segment shares a baseline across bars; every later segment starts wherever the previous one ended. Moving the focus category to the front therefore turns a hard comparison into an easy one. Use a strong colour for the focus category and quieter, related colours for the rest, so the eye goes where the story is.",[131,1120,1122],{"id":1121},"label-bars-with-their-totals","Label bars with their totals",[14,1124,1125],{},"A scaled bar shows relative magnitude, but readers often want the actual number for a few places they care about. Labels on the same layer can carry the total, placed next to the diagram, while the diagram itself stays uncluttered.",[162,1127,1129],{"className":164,"code":1128,"language":166,"meta":167,"style":167},"from qgis.core import (QgsPalLayerSettings, QgsTextFormat, QgsVectorLayerSimpleLabeling,\n                       QgsTextBufferSettings)\nfrom qgis.PyQt.QtGui import QFont\n\nlabel = QgsPalLayerSettings()\nlabel.isExpression = True\nlabel.fieldName = f\"\\\"ward_name\\\" || '\\\\n' || format_number({total_expr}, 0)\"\nfmt = QgsTextFormat()\nfmt.setFont(QFont(\"Noto Sans\", 8))\nfmt.setSize(8)\nbuf = QgsTextBufferSettings()\nbuf.setEnabled(True)\nbuf.setSize(0.8)\nfmt.setBuffer(buf)\nlabel.setFormat(fmt)\nlabel.placement = QgsPalLayerSettings.AroundPoint\nlabel.dist = 2.0\nwards.setLabeling(QgsVectorLayerSimpleLabeling(label))\nwards.setLabelsEnabled(True)\nwards.triggerRepaint()\n",[143,1130,1131,1142,1147,1158,1162,1172,1181,1220,1230,1244,1253,1263,1273,1283,1288,1293,1303,1313,1318,1327],{"__ignoreMap":167},[171,1132,1133,1135,1137,1139],{"class":173,"line":174},[171,1134,178],{"class":177},[171,1136,182],{"class":181},[171,1138,185],{"class":177},[171,1140,1141],{"class":181}," (QgsPalLayerSettings, QgsTextFormat, QgsVectorLayerSimpleLabeling,\n",[171,1143,1144],{"class":173,"line":191},[171,1145,1146],{"class":181},"                       QgsTextBufferSettings)\n",[171,1148,1149,1151,1153,1155],{"class":173,"line":197},[171,1150,178],{"class":177},[171,1152,202],{"class":181},[171,1154,185],{"class":177},[171,1156,1157],{"class":181}," QFont\n",[171,1159,1160],{"class":173,"line":210},[171,1161,227],{"emptyLinePlaceholder":226},[171,1163,1164,1167,1169],{"class":173,"line":223},[171,1165,1166],{"class":181},"label ",[171,1168,236],{"class":177},[171,1170,1171],{"class":181}," QgsPalLayerSettings()\n",[171,1173,1174,1177,1179],{"class":173,"line":230},[171,1175,1176],{"class":181},"label.isExpression ",[171,1178,236],{"class":177},[171,1180,501],{"class":249},[171,1182,1183,1186,1188,1191,1194,1197,1200,1202,1205,1208,1211,1213,1215,1217],{"class":173,"line":255},[171,1184,1185],{"class":181},"label.fieldName ",[171,1187,236],{"class":177},[171,1189,1190],{"class":177}," f",[171,1192,1193],{"class":242},"\"",[171,1195,1196],{"class":249},"\\\"",[171,1198,1199],{"class":242},"ward_name",[171,1201,1196],{"class":249},[171,1203,1204],{"class":242}," || '",[171,1206,1207],{"class":249},"\\\\",[171,1209,1210],{"class":242},"n' || format_number(",[171,1212,358],{"class":249},[171,1214,894],{"class":181},[171,1216,363],{"class":249},[171,1218,1219],{"class":242},", 0)\"\n",[171,1221,1222,1225,1227],{"class":173,"line":283},[171,1223,1224],{"class":181},"fmt ",[171,1226,236],{"class":177},[171,1228,1229],{"class":181}," QgsTextFormat()\n",[171,1231,1232,1235,1238,1240,1242],{"class":173,"line":304},[171,1233,1234],{"class":181},"fmt.setFont(QFont(",[171,1236,1237],{"class":242},"\"Noto Sans\"",[171,1239,269],{"class":181},[171,1241,596],{"class":249},[171,1243,809],{"class":181},[171,1245,1246,1249,1251],{"class":173,"line":325},[171,1247,1248],{"class":181},"fmt.setSize(",[171,1250,596],{"class":249},[171,1252,463],{"class":181},[171,1254,1255,1258,1260],{"class":173,"line":330},[171,1256,1257],{"class":181},"buf ",[171,1259,236],{"class":177},[171,1261,1262],{"class":181}," QgsTextBufferSettings()\n",[171,1264,1265,1268,1271],{"class":173,"line":341},[171,1266,1267],{"class":181},"buf.setEnabled(",[171,1269,1270],{"class":249},"True",[171,1272,463],{"class":181},[171,1274,1275,1278,1281],{"class":173,"line":381},[171,1276,1277],{"class":181},"buf.setSize(",[171,1279,1280],{"class":249},"0.8",[171,1282,463],{"class":181},[171,1284,1285],{"class":173,"line":402},[171,1286,1287],{"class":181},"fmt.setBuffer(buf)\n",[171,1289,1290],{"class":173,"line":422},[171,1291,1292],{"class":181},"label.setFormat(fmt)\n",[171,1294,1295,1298,1300],{"class":173,"line":433},[171,1296,1297],{"class":181},"label.placement ",[171,1299,236],{"class":177},[171,1301,1302],{"class":181}," QgsPalLayerSettings.AroundPoint\n",[171,1304,1305,1308,1310],{"class":173,"line":444},[171,1306,1307],{"class":181},"label.dist ",[171,1309,236],{"class":177},[171,1311,1312],{"class":249}," 2.0\n",[171,1314,1315],{"class":173,"line":466},[171,1316,1317],{"class":181},"wards.setLabeling(QgsVectorLayerSimpleLabeling(label))\n",[171,1319,1320,1323,1325],{"class":173,"line":482},[171,1321,1322],{"class":181},"wards.setLabelsEnabled(",[171,1324,1270],{"class":249},[171,1326,463],{"class":181},[171,1328,1329],{"class":173,"line":493},[171,1330,547],{"class":181},[14,1332,1333,1335,1336,1339,1340,1344],{},[551,1334,553],{}," The label expression joins the ward name and its formatted total on two lines, reusing the same total expression that sizes the bars, so the number always matches the bar. ",[143,1337,1338],{},"format_number"," adds thousands separators. Placing labels around the point with a small offset, and letting the labelling engine treat diagrams as obstacles, keeps text off the bars. A text buffer keeps the label legible over the base map. ",[21,1341,1343],{"href":1342},"\u002Fpyqgis-cartography-visualization\u002Flabeling-and-annotations\u002Fcontrol-label-placement-and-collisions-pyqgis\u002F","Label placement and collisions"," covers fine-tuning when labels and diagrams compete for space.",[131,1346,1348],{"id":1347},"combine-diagrams-on-one-feature","Combine diagrams on one feature",[14,1350,1351,1352,1354],{},"QGIS 3.40 introduced ",[143,1353,149],{},", which draws several diagrams — of any type — side by side or one above another for each feature. That allows, for example, a bar for dwellings by tenure next to a pie of household size.",[14,1356,1357],{},[29,1358,1361,1364,1367,1370,1385,1388,1392,1397,1401,1405,1412,1414,1419,1424,1428,1431,1435,1439,1443,1446,1451],{"viewBox":1359,"role":32,"ariaLabel":1360,"xmlns":34},"0 0 760 212","A container diagram holding a stacked bar and a pie side by side for each feature, each with its own settings",[36,1362,1363],{},"Several diagrams per feature",[40,1365,1366],{},"A stacked diagram container holds two sub-diagrams for each feature: a horizontal stacked bar of tenure and a small pie of household size, arranged horizontally with a small spacing. Each sub-diagram has its own settings, categories and colours. The container is available from QGIS 3.40.",[44,1368],{"x":46,"y":46,"width":47,"height":1369,"fill":49},"212",[1371,1372,1373],"defs",{},[1374,1375,1381],"marker",{"id":1376,"viewBox":1377,"refX":596,"refY":1378,"markerWidth":1379,"markerHeight":1379,"orient":1380},"stkMultiArrow","0 0 10 10","5","7","auto-start-reverse",[1382,1383],"path",{"d":1384,"fill":64},"M0 0 L10 5 L0 10 z",[51,1386,1387],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"QgsStackedDiagram: one container, several charts",[44,1389],{"x":594,"y":112,"width":1390,"height":69,"rx":596,"fill":74,"stroke":597,"style":1391},"300","stroke-width:2",[51,1393,149],{"x":1394,"y":1395,"style":1396,"fill":56,"textAnchor":57},"174","102.78","text-anchor:middle;font-size:11.5px;font-family:sans-serif;font-weight:bold",[51,1398,1400],{"x":1394,"y":1399,"style":121,"fill":597,"textAnchor":57},"128.78","3.40+",[51,1402,1404],{"x":1394,"y":1403,"style":121,"fill":597,"textAnchor":57},"154.78","horizontal or vertical",[173,1406],{"x1":1407,"y1":1408,"x2":1409,"y2":1410,"stroke":64,"style":1411},"324","125","366","100","stroke-width:1.8;marker-end:url(#stkMultiArrow)",[173,1413],{"x1":1407,"y1":1408,"x2":1409,"y2":83,"stroke":64,"style":1411},[44,1415],{"x":1416,"y":619,"width":119,"height":1417,"rx":596,"fill":1418,"stroke":73,"style":1391},"370","56","#eef7f4",[51,1420,1423],{"x":1421,"y":1422,"style":1396,"fill":73,"textAnchor":57},"470","91.78","stacked bar",[51,1425,1427],{"x":1421,"y":1426,"style":121,"fill":597,"textAnchor":57},"111.78","tenure",[44,1429],{"x":1416,"y":611,"width":119,"height":1417,"rx":596,"fill":1430,"stroke":84,"style":1391},"#fdf2e2",[51,1432,1434],{"x":1421,"y":1433,"style":1396,"fill":84,"textAnchor":57},"161.78","pie",[51,1436,1438],{"x":1421,"y":1437,"style":121,"fill":597,"textAnchor":57},"181.78","household size",[44,1440],{"x":1441,"y":62,"width":112,"height":1442,"rx":46,"fill":73,"stroke":74,"style":75},"600","14",[44,1444],{"x":1445,"y":62,"width":646,"height":1442,"rx":46,"fill":79,"stroke":74,"style":75},"660",[1447,1448],"circle",{"cx":1449,"cy":1450,"r":1442,"fill":84,"stroke":74,"style":598},"720","99",[51,1452,1454],{"x":1453,"y":611,"style":121,"fill":597,"textAnchor":57},"668","drawn together",[162,1456,1458],{"className":164,"code":1457,"language":166,"meta":167,"style":167},"from qgis.core import QgsStackedDiagram, QgsPieDiagram\n\nstacked = QgsStackedDiagram()\nstacked.setStackedDiagramMode(QgsStackedDiagram.Horizontal)\nstacked.setStackedDiagramSpacing(1.0)\n\npie_settings = QgsDiagramSettings()\npie_settings.categoryAttributes = ['\"hh_1\"', '\"hh_2\"', '\"hh_3plus\"']\npie_settings.categoryColors = [QColor(\"#b45309\"), QColor(\"#d97706\"), QColor(\"#92400e\")]\npie_settings.categoryLabels = [\"1 person\", \"2 people\", \"3+\"]\npie_settings.size = QSizeF(6, 6)\npie_settings.enabled = True\n\nstacked.addSubDiagram(QgsStackedBarDiagram(), settings)\nstacked.addSubDiagram(QgsPieDiagram(), pie_settings)\ncombo = QgsSingleCategoryDiagramRenderer()\ncombo.setDiagram(stacked)\ncombo.setDiagramSettings(settings)\nwards.setDiagramRenderer(combo)\nwards.triggerRepaint()\n",[143,1459,1460,1471,1475,1485,1490,1500,1504,1513,1537,1562,1586,1604,1613,1617,1622,1627,1636,1641,1646,1651],{"__ignoreMap":167},[171,1461,1462,1464,1466,1468],{"class":173,"line":174},[171,1463,178],{"class":177},[171,1465,182],{"class":181},[171,1467,185],{"class":177},[171,1469,1470],{"class":181}," QgsStackedDiagram, QgsPieDiagram\n",[171,1472,1473],{"class":173,"line":191},[171,1474,227],{"emptyLinePlaceholder":226},[171,1476,1477,1480,1482],{"class":173,"line":197},[171,1478,1479],{"class":181},"stacked ",[171,1481,236],{"class":177},[171,1483,1484],{"class":181}," QgsStackedDiagram()\n",[171,1486,1487],{"class":173,"line":210},[171,1488,1489],{"class":181},"stacked.setStackedDiagramMode(QgsStackedDiagram.Horizontal)\n",[171,1491,1492,1495,1498],{"class":173,"line":223},[171,1493,1494],{"class":181},"stacked.setStackedDiagramSpacing(",[171,1496,1497],{"class":249},"1.0",[171,1499,463],{"class":181},[171,1501,1502],{"class":173,"line":230},[171,1503,227],{"emptyLinePlaceholder":226},[171,1505,1506,1509,1511],{"class":173,"line":255},[171,1507,1508],{"class":181},"pie_settings ",[171,1510,236],{"class":177},[171,1512,338],{"class":181},[171,1514,1515,1518,1520,1522,1525,1527,1530,1532,1535],{"class":173,"line":283},[171,1516,1517],{"class":181},"pie_settings.categoryAttributes ",[171,1519,236],{"class":177},[171,1521,349],{"class":181},[171,1523,1524],{"class":242},"'\"hh_1\"'",[171,1526,269],{"class":181},[171,1528,1529],{"class":242},"'\"hh_2\"'",[171,1531,269],{"class":181},[171,1533,1534],{"class":242},"'\"hh_3plus\"'",[171,1536,252],{"class":181},[171,1538,1539,1542,1544,1547,1549,1552,1555,1557,1560],{"class":173,"line":304},[171,1540,1541],{"class":181},"pie_settings.categoryColors ",[171,1543,236],{"class":177},[171,1545,1546],{"class":181}," [QColor(",[171,1548,319],{"class":242},[171,1550,1551],{"class":181},"), QColor(",[171,1553,1554],{"class":242},"\"#d97706\"",[171,1556,1551],{"class":181},[171,1558,1559],{"class":242},"\"#92400e\"",[171,1561,322],{"class":181},[171,1563,1564,1567,1569,1571,1574,1576,1579,1581,1584],{"class":173,"line":325},[171,1565,1566],{"class":181},"pie_settings.categoryLabels ",[171,1568,236],{"class":177},[171,1570,349],{"class":181},[171,1572,1573],{"class":242},"\"1 person\"",[171,1575,269],{"class":181},[171,1577,1578],{"class":242},"\"2 people\"",[171,1580,269],{"class":181},[171,1582,1583],{"class":242},"\"3+\"",[171,1585,252],{"class":181},[171,1587,1588,1591,1593,1595,1598,1600,1602],{"class":173,"line":330},[171,1589,1590],{"class":181},"pie_settings.size ",[171,1592,236],{"class":177},[171,1594,452],{"class":181},[171,1596,1597],{"class":249},"6",[171,1599,269],{"class":181},[171,1601,1597],{"class":249},[171,1603,463],{"class":181},[171,1605,1606,1609,1611],{"class":173,"line":341},[171,1607,1608],{"class":181},"pie_settings.enabled ",[171,1610,236],{"class":177},[171,1612,501],{"class":249},[171,1614,1615],{"class":173,"line":381},[171,1616,227],{"emptyLinePlaceholder":226},[171,1618,1619],{"class":173,"line":402},[171,1620,1621],{"class":181},"stacked.addSubDiagram(QgsStackedBarDiagram(), settings)\n",[171,1623,1624],{"class":173,"line":422},[171,1625,1626],{"class":181},"stacked.addSubDiagram(QgsPieDiagram(), pie_settings)\n",[171,1628,1629,1632,1634],{"class":173,"line":433},[171,1630,1631],{"class":181},"combo ",[171,1633,236],{"class":177},[171,1635,517],{"class":181},[171,1637,1638],{"class":173,"line":444},[171,1639,1640],{"class":181},"combo.setDiagram(stacked)\n",[171,1642,1643],{"class":173,"line":466},[171,1644,1645],{"class":181},"combo.setDiagramSettings(settings)\n",[171,1647,1648],{"class":173,"line":482},[171,1649,1650],{"class":181},"wards.setDiagramRenderer(combo)\n",[171,1652,1653],{"class":173,"line":493},[171,1654,547],{"class":181},[14,1656,1657,1659,1660,1663],{},[551,1658,553],{}," Each sub-diagram keeps its own settings, so the bar and the pie have independent categories, colours and sizes. The container arranges them horizontally or vertically with a spacing in the diagram's size unit. Use this sparingly: two small charts per feature is about the limit before a map becomes a dashboard. Check the exact method names with ",[143,1661,1662],{},"help(QgsStackedDiagram)"," on your version, as the class is new.",[131,1665,1667],{"id":1666},"check-the-result-with-a-readers-eyes","Check the result with a reader's eyes",[14,1669,1670],{},"Before publishing, look at the map the way a reader will. Can you find the ward with the most social housing without reading any numbers? Can you tell which wards are large and which small? Does any bar run into a neighbour or off the edge of the page? Stacked bars reward this check because their two messages — total and mix — can compete: if every bar is long, composition is easy to read but totals blur together; if lengths vary enormously, small wards' segments become slivers. When one message clearly matters more, favour it — percentage bars for composition, a separate proportional symbol map for totals — rather than forcing one diagram to do both badly. A quick export of the layout to PDF at the final size, viewed at 100 %, is the most reliable test of all.",[131,1672,1674],{"id":1673},"qgis-version-compatibility","QGIS version compatibility",[14,1676,1677,1679,1680,1682,1683,150],{},[143,1678,145],{}," requires QGIS 3.12 or newer and is available on 3.34 LTR, 3.40 LTR and QGIS 4. ",[143,1681,149],{}," requires 3.40. On QGIS 4, orientation and mode enums are scoped, for example ",[143,1684,1685],{},"QgsDiagramSettings.DiagramOrientation.Right",[131,1687,1689],{"id":1688},"troubleshooting","Troubleshooting",[136,1691,1692,1698,1707,1713],{},[139,1693,1694,1697],{},[551,1695,1696],{},"Bars all have the same length."," A single-category renderer is in use; switch to the interpolated renderer for magnitude.",[139,1699,1700,1703,1704,1706],{},[551,1701,1702],{},"Some wards have no bar."," A part is NULL and was not wrapped in ",[143,1705,557],{},", or the total is zero in a percentage bar.",[139,1708,1709,1712],{},[551,1710,1711],{},"Segments look different in the legend."," Colours and labels were not reordered together with the attributes.",[139,1714,1715,1723],{},[551,1716,1717,1720,1721,150],{},[143,1718,1719],{},"AttributeError"," on ",[143,1722,149],{}," QGIS is older than 3.40.",[131,1725,1727],{"id":1726},"conclusion","Conclusion",[14,1729,1730,1731,1733,1734,1736],{},"Use ",[143,1732,145],{}," when both totals and composition matter, scale length by the total from zero with the interpolated renderer, switch to equal-length percentage bars when totals vary too much, put the focus category first for a common baseline, and combine diagrams with ",[143,1735,149],{}," on 3.40 or newer only when two charts genuinely help.",[131,1738,1740],{"id":1739},"frequently-asked-questions","Frequently Asked Questions",[14,1742,1743,1746],{},[551,1744,1745],{},"Vertical or horizontal bars?","\nHorizontal usually fits better under labels and between features; vertical suits point features in sparse areas.",[14,1748,1749,1752],{},[551,1750,1751],{},"Can segments have value labels?","\nNot inside the diagram. Add labels with an expression that formats the values, placed next to the bar.",[14,1754,1755,1758],{},[551,1756,1757],{},"How many segments are too many?","\nMore than five or six become hard to tell apart at map size. Group categories first.",[14,1760,1761,1764],{},[551,1762,1763],{},"Can a stacked bar show negative parts?","\nNo. Diagrams assume non-negative values.",[131,1766,1768],{"id":1767},"related","Related",[136,1770,1771,1776,1782,1788,1794],{},[139,1772,1773,1775],{},[21,1774,24],{"href":23}," — the guide this recipe belongs to",[139,1777,1778],{},[21,1779,1781],{"href":1780},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-histogram-bar-diagrams-pyqgis\u002F","Add Histogram Bar Diagrams in PyQGIS",[139,1783,1784],{},[21,1785,1787],{"href":1786},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-pie-chart-diagrams-pyqgis\u002F","Add Pie Chart Diagrams to a Layer in PyQGIS",[139,1789,1790],{},[21,1791,1793],{"href":1792},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fsize-diagrams-by-attribute-pyqgis\u002F","Size Diagrams by Attribute in PyQGIS",[139,1795,1796],{},[21,1797,1799],{"href":1798},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-diagram-legend-and-text-diagrams-pyqgis\u002F","Add Diagram Legends and Text Diagrams in PyQGIS",[1801,1802,1803],"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 .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);}html pre.shiki code .sjoCn, html code.shiki .sjoCn{--shiki-default:#9AA79F}",{"title":167,"searchDepth":191,"depth":191,"links":1805},[1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818],{"id":133,"depth":191,"text":134},{"id":156,"depth":191,"text":157},{"id":569,"depth":191,"text":570},{"id":857,"depth":191,"text":858},{"id":961,"depth":191,"text":962},{"id":1121,"depth":191,"text":1122},{"id":1347,"depth":191,"text":1348},{"id":1666,"depth":191,"text":1667},{"id":1673,"depth":191,"text":1674},{"id":1688,"depth":191,"text":1689},{"id":1726,"depth":191,"text":1727},{"id":1739,"depth":191,"text":1740},{"id":1767,"depth":191,"text":1768},"Show totals and their composition in one bar per feature with QgsStackedBarDiagram — segment order and colours, scaling bar length to the total, percentage bars for pure composition, and combining several diagrams per feature with QgsStackedDiagram.","md",{"slug":1822,"type":1823,"breadcrumb":1824,"datePublished":1825,"dateModified":1825},"add-stacked-bar-diagrams-pyqgis","article","Add Stacked Bar Diagrams","2026-10-02","\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-stacked-bar-diagrams-pyqgis",{"title":5,"description":1819},"pyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-stacked-bar-diagrams-pyqgis\u002Findex","lwBBgu8hIkLmf1Ox062Brt8wmbEzwp-5yHUowtxVErY",1790966252900]