[{"data":1,"prerenderedAt":1806},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-pie-chart-in-excel-with-openpyxl":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-pie-chart-in-excel-with-openpyxl":1799},{"id":4,"title":5,"body":6,"dateModified":1769,"datePublished":1769,"description":1770,"extension":1771,"faq":1772,"meta":1781,"navigation":232,"path":1792,"seo":1793,"slug":1795,"stem":1796,"type":1797,"__hash__":1798},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-pie-chart-in-excel-with-openpyxl\u002Findex.md","Create a Pie Chart in Excel with openpyxl",{"type":7,"value":8,"toc":1755},"minimark",[9,13,22,150,155,181,184,188,191,462,465,469,650,670,680,684,687,756,759,766,770,777,972,977,980,1104,1108,1111,1278,1356,1359,1363,1366,1470,1473,1477,1613,1617,1620,1628,1632,1644,1648,1669,1681,1698,1704,1708,1711,1720,1723,1751],[10,11,12],"p",{},"A pie chart does one thing well: showing that a single share dominates, or that one of three or four parts is much larger than the rest. Past that it becomes hard work — human eyes compare angles badly, and two slices within a few percentage points of each other look identical.",[10,14,15,16,21],{},"So this guide covers both halves of the job: how to build a good pie chart in openpyxl, and how to tell when the same data belongs in a bar chart instead. It is part of ",[17,18,20],"a",{"href":19},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002F","Creating Charts in Excel with openpyxl",".",[23,24,32,33,32,37,32,41,32,48,32,55,32,60,32,64,32,68,32,74,32,78,32,82,32,87,32,92,32,99,32,105,32,109,32,113,32,116,32,119,32,122,32,126,32,130,32,133,32,136,32,140,32,144,32,147],"svg",{"viewBox":25,"role":26,"ariaLabelledBy":27,"xmlns":30,"style":31},"0 0 740 250","img",[28,29],"pie-when-t","pie-when-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:740px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[34,35,36],"title",{"id":28},"When a pie reads well and when it does not",[38,39,40],"desc",{"id":29},"With three parts of clearly different sizes, a pie makes the dominant share obvious at a glance. With eight similar categories the slices become indistinguishable wedges that can only be read from their labels, at which point a sorted bar chart conveys the same information immediately.",[42,43],"rect",{"x":44,"y":44,"width":45,"height":46,"fill":47},"0","740","250","#ffffff",[49,50,54],"text",{"x":51,"y":52,"style":53},"184","32","font-size:12.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","three uneven parts — a pie works",[56,57],"path",{"d":58,"fill":59},"M 130 130 L 130 60 A 70 70 0 0 1 190 165 Z","#5b5cf0",[56,61],{"d":62,"fill":63},"M 130 130 L 190 165 A 70 70 0 0 1 78 168 Z","#0f766e",[56,65],{"d":66,"fill":67},"M 130 130 L 78 168 A 70 70 0 0 1 130 60 Z","#b4740a",[49,69,73],{"x":70,"y":71,"style":72},"248","96","font-size:11px;fill:var(--text,#172033)","Core 55%",[49,75,77],{"x":70,"y":76,"style":72},"126","Services 28%",[49,79,81],{"x":70,"y":80,"style":72},"156","Other 17%",[49,83,86],{"x":51,"y":84,"style":85},"214","font-size:11px;fill:var(--muted,#5b6780);text-anchor:middle","the dominant share is obvious without reading a number",[49,88,91],{"x":89,"y":52,"style":90},"556","font-size:12.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","eight similar parts — use a bar",[42,93],{"x":94,"y":95,"width":96,"height":97,"rx":98,"fill":59},"424","56","180","14","2",[49,100,104],{"x":101,"y":102,"style":103},"614","67","font-size:10.5px;fill:var(--muted,#5b6780)","14%",[42,106],{"x":94,"y":107,"width":108,"height":97,"rx":98,"fill":59},"76","170",[49,110,112],{"x":101,"y":111,"style":103},"87","13%",[42,114],{"x":94,"y":71,"width":115,"height":97,"rx":98,"fill":59},"164",[49,117,112],{"x":101,"y":118,"style":103},"107",[42,120],{"x":94,"y":121,"width":80,"height":97,"rx":98,"fill":59},"116",[49,123,125],{"x":101,"y":124,"style":103},"127","12%",[42,127],{"x":94,"y":128,"width":129,"height":97,"rx":98,"fill":59},"136","150",[49,131,125],{"x":101,"y":132,"style":103},"147",[42,134],{"x":94,"y":80,"width":135,"height":97,"rx":98,"fill":59},"140",[49,137,139],{"x":101,"y":138,"style":103},"167","11%",[42,141],{"x":94,"y":142,"width":143,"height":97,"rx":98,"fill":59},"176","132",[49,145,139],{"x":101,"y":146,"style":103},"187",[49,148,149],{"x":89,"y":84,"style":85},"ranking and near-ties are readable; as wedges they would not be",[151,152,154],"h2",{"id":153},"prerequisites","Prerequisites",[156,157,162],"pre",{"className":158,"code":159,"language":160,"meta":161,"style":161},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[163,164,165],"code",{"__ignoreMap":161},[166,167,170,174,178],"span",{"class":168,"line":169},"line",1,[166,171,173],{"class":172},"sMTad","pip",[166,175,177],{"class":176},"srMev"," install",[166,179,180],{"class":176}," openpyxl\n",[10,182,183],{},"No Excel installation is needed. openpyxl writes the chart definition into the file, and Excel or LibreOffice renders it when the workbook is opened.",[151,185,187],{"id":186},"step-1-write-the-data-the-chart-plots","Step 1: Write the data the chart plots",[10,189,190],{},"An Excel chart references cells, so the categories and values have to be in the sheet:",[156,192,196],{"className":193,"code":194,"language":195,"meta":161,"style":161},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook\nfrom openpyxl.chart import PieChart, Reference\n\nwb = Workbook()\nws = wb.active\nws.title = \"Revenue\"\n\nrows = [\n    (\"Category\", \"Revenue\"),\n    (\"Core products\", 552_000),\n    (\"Services\", 281_000),\n    (\"Support\", 96_000),\n    (\"Training\", 71_000),\n]\nfor row in rows:\n    ws.append(row)\n\nfor cell in ws[\"B\"][1:]:\n    cell.number_format = '#,##0'\nws.column_dimensions[\"A\"].width = 18\nws.column_dimensions[\"B\"].width = 14\n","python",[163,197,198,214,227,234,246,257,268,273,284,302,318,333,348,363,369,384,390,395,420,431,448],{"__ignoreMap":161},[166,199,200,204,208,211],{"class":168,"line":169},[166,201,203],{"class":202},"s-kum","from",[166,205,207],{"class":206},"skGVy"," openpyxl ",[166,209,210],{"class":202},"import",[166,212,213],{"class":206}," Workbook\n",[166,215,217,219,222,224],{"class":168,"line":216},2,[166,218,203],{"class":202},[166,220,221],{"class":206}," openpyxl.chart ",[166,223,210],{"class":202},[166,225,226],{"class":206}," PieChart, Reference\n",[166,228,230],{"class":168,"line":229},3,[166,231,233],{"emptyLinePlaceholder":232},true,"\n",[166,235,237,240,243],{"class":168,"line":236},4,[166,238,239],{"class":206},"wb ",[166,241,242],{"class":202},"=",[166,244,245],{"class":206}," Workbook()\n",[166,247,249,252,254],{"class":168,"line":248},5,[166,250,251],{"class":206},"ws ",[166,253,242],{"class":202},[166,255,256],{"class":206}," wb.active\n",[166,258,260,263,265],{"class":168,"line":259},6,[166,261,262],{"class":206},"ws.title ",[166,264,242],{"class":202},[166,266,267],{"class":176}," \"Revenue\"\n",[166,269,271],{"class":168,"line":270},7,[166,272,233],{"emptyLinePlaceholder":232},[166,274,276,279,281],{"class":168,"line":275},8,[166,277,278],{"class":206},"rows ",[166,280,242],{"class":202},[166,282,283],{"class":206}," [\n",[166,285,287,290,293,296,299],{"class":168,"line":286},9,[166,288,289],{"class":206},"    (",[166,291,292],{"class":176},"\"Category\"",[166,294,295],{"class":206},", ",[166,297,298],{"class":176},"\"Revenue\"",[166,300,301],{"class":206},"),\n",[166,303,305,307,310,312,316],{"class":168,"line":304},10,[166,306,289],{"class":206},[166,308,309],{"class":176},"\"Core products\"",[166,311,295],{"class":206},[166,313,315],{"class":314},"sP0c6","552_000",[166,317,301],{"class":206},[166,319,321,323,326,328,331],{"class":168,"line":320},11,[166,322,289],{"class":206},[166,324,325],{"class":176},"\"Services\"",[166,327,295],{"class":206},[166,329,330],{"class":314},"281_000",[166,332,301],{"class":206},[166,334,336,338,341,343,346],{"class":168,"line":335},12,[166,337,289],{"class":206},[166,339,340],{"class":176},"\"Support\"",[166,342,295],{"class":206},[166,344,345],{"class":314},"96_000",[166,347,301],{"class":206},[166,349,351,353,356,358,361],{"class":168,"line":350},13,[166,352,289],{"class":206},[166,354,355],{"class":176},"\"Training\"",[166,357,295],{"class":206},[166,359,360],{"class":314},"71_000",[166,362,301],{"class":206},[166,364,366],{"class":168,"line":365},14,[166,367,368],{"class":206},"]\n",[166,370,372,375,378,381],{"class":168,"line":371},15,[166,373,374],{"class":202},"for",[166,376,377],{"class":206}," row ",[166,379,380],{"class":202},"in",[166,382,383],{"class":206}," rows:\n",[166,385,387],{"class":168,"line":386},16,[166,388,389],{"class":206},"    ws.append(row)\n",[166,391,393],{"class":168,"line":392},17,[166,394,233],{"emptyLinePlaceholder":232},[166,396,398,400,403,405,408,411,414,417],{"class":168,"line":397},18,[166,399,374],{"class":202},[166,401,402],{"class":206}," cell ",[166,404,380],{"class":202},[166,406,407],{"class":206}," ws[",[166,409,410],{"class":176},"\"B\"",[166,412,413],{"class":206},"][",[166,415,416],{"class":314},"1",[166,418,419],{"class":206},":]:\n",[166,421,423,426,428],{"class":168,"line":422},19,[166,424,425],{"class":206},"    cell.number_format ",[166,427,242],{"class":202},[166,429,430],{"class":176}," '#,##0'\n",[166,432,434,437,440,443,445],{"class":168,"line":433},20,[166,435,436],{"class":206},"ws.column_dimensions[",[166,438,439],{"class":176},"\"A\"",[166,441,442],{"class":206},"].width ",[166,444,242],{"class":202},[166,446,447],{"class":314}," 18\n",[166,449,451,453,455,457,459],{"class":168,"line":450},21,[166,452,436],{"class":206},[166,454,410],{"class":176},[166,456,442],{"class":206},[166,458,242],{"class":202},[166,460,461],{"class":314}," 14\n",[10,463,464],{},"Four categories is about the practical maximum for a pie. If your data has twelve, group the small ones into an \"Other\" row before charting — the chart is a summary, and a slice representing 0.4% conveys nothing except clutter.",[151,466,468],{"id":467},"step-2-build-the-chart","Step 2: Build the chart",[156,470,472],{"className":193,"code":471,"language":195,"meta":161,"style":161},"chart = PieChart()\nchart.title = \"Revenue by category\"\n\nlabels = Reference(ws, min_col=1, min_row=2, max_row=5)          # no header\ndata = Reference(ws, min_col=2, min_row=1, max_row=5)            # header included\n\nchart.add_data(data, titles_from_data=True)\nchart.set_categories(labels)\nchart.height = 9          # centimetres\nchart.width = 14\n\nws.add_chart(chart, \"D2\")\nwb.save(\"pie.xlsx\")\n",[163,473,474,484,494,498,542,579,583,599,604,617,626,630,640],{"__ignoreMap":161},[166,475,476,479,481],{"class":168,"line":169},[166,477,478],{"class":206},"chart ",[166,480,242],{"class":202},[166,482,483],{"class":206}," PieChart()\n",[166,485,486,489,491],{"class":168,"line":216},[166,487,488],{"class":206},"chart.title ",[166,490,242],{"class":202},[166,492,493],{"class":176}," \"Revenue by category\"\n",[166,495,496],{"class":168,"line":229},[166,497,233],{"emptyLinePlaceholder":232},[166,499,500,503,505,508,512,514,516,518,521,523,525,527,530,532,535,538],{"class":168,"line":236},[166,501,502],{"class":206},"labels ",[166,504,242],{"class":202},[166,506,507],{"class":206}," Reference(ws, ",[166,509,511],{"class":510},"sa561","min_col",[166,513,242],{"class":202},[166,515,416],{"class":314},[166,517,295],{"class":206},[166,519,520],{"class":510},"min_row",[166,522,242],{"class":202},[166,524,98],{"class":314},[166,526,295],{"class":206},[166,528,529],{"class":510},"max_row",[166,531,242],{"class":202},[166,533,534],{"class":314},"5",[166,536,537],{"class":206},")          ",[166,539,541],{"class":540},"s-wDw","# no header\n",[166,543,544,547,549,551,553,555,557,559,561,563,565,567,569,571,573,576],{"class":168,"line":248},[166,545,546],{"class":206},"data ",[166,548,242],{"class":202},[166,550,507],{"class":206},[166,552,511],{"class":510},[166,554,242],{"class":202},[166,556,98],{"class":314},[166,558,295],{"class":206},[166,560,520],{"class":510},[166,562,242],{"class":202},[166,564,416],{"class":314},[166,566,295],{"class":206},[166,568,529],{"class":510},[166,570,242],{"class":202},[166,572,534],{"class":314},[166,574,575],{"class":206},")            ",[166,577,578],{"class":540},"# header included\n",[166,580,581],{"class":168,"line":259},[166,582,233],{"emptyLinePlaceholder":232},[166,584,585,588,591,593,596],{"class":168,"line":270},[166,586,587],{"class":206},"chart.add_data(data, ",[166,589,590],{"class":510},"titles_from_data",[166,592,242],{"class":202},[166,594,595],{"class":314},"True",[166,597,598],{"class":206},")\n",[166,600,601],{"class":168,"line":275},[166,602,603],{"class":206},"chart.set_categories(labels)\n",[166,605,606,609,611,614],{"class":168,"line":286},[166,607,608],{"class":206},"chart.height ",[166,610,242],{"class":202},[166,612,613],{"class":314}," 9",[166,615,616],{"class":540},"          # centimetres\n",[166,618,619,622,624],{"class":168,"line":304},[166,620,621],{"class":206},"chart.width ",[166,623,242],{"class":202},[166,625,461],{"class":314},[166,627,628],{"class":168,"line":320},[166,629,233],{"emptyLinePlaceholder":232},[166,631,632,635,638],{"class":168,"line":335},[166,633,634],{"class":206},"ws.add_chart(chart, ",[166,636,637],{"class":176},"\"D2\"",[166,639,598],{"class":206},[166,641,642,645,648],{"class":168,"line":350},[166,643,644],{"class":206},"wb.save(",[166,646,647],{"class":176},"\"pie.xlsx\"",[166,649,598],{"class":206},[10,651,652,653,656,657,661,662,665,666,669],{},"The asymmetry between the two ",[163,654,655],{},"Reference"," calls is the thing to get right and the source of most pie-chart bugs. The ",[658,659,660],"em",{},"values"," reference starts at the header row because ",[163,663,664],{},"titles_from_data=True"," takes the series name from that first cell. The ",[658,667,668],{},"categories"," reference starts at the first data row, because a category list has no header. Get them the same way round and you either lose a slice or get a series called \"552000\".",[10,671,672,675,676,679],{},[163,673,674],{},"height"," and ",[163,677,678],{},"width"," are in centimetres, unlike xlsxwriter's pixels — a small difference that matters when porting code between the two.",[151,681,683],{"id":682},"step-3-show-percentages-rather-than-raw-numbers","Step 3: Show percentages rather than raw numbers",[10,685,686],{},"A pie's whole subject is proportion, so the labels should say so:",[156,688,690],{"className":193,"code":689,"language":195,"meta":161,"style":161},"from openpyxl.chart.label import DataLabelList\n\nchart.dataLabels = DataLabelList()\nchart.dataLabels.showPercent = True\nchart.dataLabels.showVal = False\nchart.dataLabels.showCatName = False\nchart.dataLabels.showLegendKey = False\n",[163,691,692,704,708,718,728,738,747],{"__ignoreMap":161},[166,693,694,696,699,701],{"class":168,"line":169},[166,695,203],{"class":202},[166,697,698],{"class":206}," openpyxl.chart.label ",[166,700,210],{"class":202},[166,702,703],{"class":206}," DataLabelList\n",[166,705,706],{"class":168,"line":216},[166,707,233],{"emptyLinePlaceholder":232},[166,709,710,713,715],{"class":168,"line":229},[166,711,712],{"class":206},"chart.dataLabels ",[166,714,242],{"class":202},[166,716,717],{"class":206}," DataLabelList()\n",[166,719,720,723,725],{"class":168,"line":236},[166,721,722],{"class":206},"chart.dataLabels.showPercent ",[166,724,242],{"class":202},[166,726,727],{"class":314}," True\n",[166,729,730,733,735],{"class":168,"line":248},[166,731,732],{"class":206},"chart.dataLabels.showVal ",[166,734,242],{"class":202},[166,736,737],{"class":314}," False\n",[166,739,740,743,745],{"class":168,"line":259},[166,741,742],{"class":206},"chart.dataLabels.showCatName ",[166,744,242],{"class":202},[166,746,737],{"class":314},[166,748,749,752,754],{"class":168,"line":270},[166,750,751],{"class":206},"chart.dataLabels.showLegendKey ",[166,753,242],{"class":202},[166,755,737],{"class":314},[10,757,758],{},"Excel computes the percentages itself from the plotted values, so they always total 100 — which is better than pre-computing them in pandas, where rounding can leave you presenting a chart that adds to 99.9%.",[10,760,761,762,765],{},"Set ",[163,763,764],{},"showCatName = True"," and drop the legend if you would rather label the slices directly. That is usually the more readable choice: a legend forces the reader to match colours to names, while a labelled slice does not.",[151,767,769],{"id":768},"step-4-colour-and-explode-individual-slices","Step 4: Colour and explode individual slices",[10,771,772,773,776],{},"Assign a ",[163,774,775],{},"DataPoint"," per slice to control its fill, and use the same technique to pull one slice out for emphasis:",[156,778,780],{"className":193,"code":779,"language":195,"meta":161,"style":161},"from openpyxl.chart.marker import DataPoint\nfrom openpyxl.chart.shapes import GraphicalProperties\n\nCOLOURS = [\"5B5CF0\", \"0F766E\", \"B4740A\", \"BE185D\"]\n\nseries = chart.series[0]\nseries.data_points = []\nfor idx, colour in enumerate(COLOURS):\n    point = DataPoint(idx=idx)\n    point.graphicalProperties = GraphicalProperties(solidFill=colour)\n    if idx == 0:\n        point.explosion = 12          # pull the first slice out slightly\n    series.data_points.append(point)\n\nwb.save(\"pie.xlsx\")\n",[163,781,782,794,806,810,841,845,859,869,889,907,925,942,955,960,964],{"__ignoreMap":161},[166,783,784,786,789,791],{"class":168,"line":169},[166,785,203],{"class":202},[166,787,788],{"class":206}," openpyxl.chart.marker ",[166,790,210],{"class":202},[166,792,793],{"class":206}," DataPoint\n",[166,795,796,798,801,803],{"class":168,"line":216},[166,797,203],{"class":202},[166,799,800],{"class":206}," openpyxl.chart.shapes ",[166,802,210],{"class":202},[166,804,805],{"class":206}," GraphicalProperties\n",[166,807,808],{"class":168,"line":229},[166,809,233],{"emptyLinePlaceholder":232},[166,811,812,815,818,821,824,826,829,831,834,836,839],{"class":168,"line":236},[166,813,814],{"class":314},"COLOURS",[166,816,817],{"class":202}," =",[166,819,820],{"class":206}," [",[166,822,823],{"class":176},"\"5B5CF0\"",[166,825,295],{"class":206},[166,827,828],{"class":176},"\"0F766E\"",[166,830,295],{"class":206},[166,832,833],{"class":176},"\"B4740A\"",[166,835,295],{"class":206},[166,837,838],{"class":176},"\"BE185D\"",[166,840,368],{"class":206},[166,842,843],{"class":168,"line":248},[166,844,233],{"emptyLinePlaceholder":232},[166,846,847,850,852,855,857],{"class":168,"line":259},[166,848,849],{"class":206},"series ",[166,851,242],{"class":202},[166,853,854],{"class":206}," chart.series[",[166,856,44],{"class":314},[166,858,368],{"class":206},[166,860,861,864,866],{"class":168,"line":270},[166,862,863],{"class":206},"series.data_points ",[166,865,242],{"class":202},[166,867,868],{"class":206}," []\n",[166,870,871,873,876,878,881,884,886],{"class":168,"line":275},[166,872,374],{"class":202},[166,874,875],{"class":206}," idx, colour ",[166,877,380],{"class":202},[166,879,880],{"class":314}," enumerate",[166,882,883],{"class":206},"(",[166,885,814],{"class":314},[166,887,888],{"class":206},"):\n",[166,890,891,894,896,899,902,904],{"class":168,"line":286},[166,892,893],{"class":206},"    point ",[166,895,242],{"class":202},[166,897,898],{"class":206}," DataPoint(",[166,900,901],{"class":510},"idx",[166,903,242],{"class":202},[166,905,906],{"class":206},"idx)\n",[166,908,909,912,914,917,920,922],{"class":168,"line":304},[166,910,911],{"class":206},"    point.graphicalProperties ",[166,913,242],{"class":202},[166,915,916],{"class":206}," GraphicalProperties(",[166,918,919],{"class":510},"solidFill",[166,921,242],{"class":202},[166,923,924],{"class":206},"colour)\n",[166,926,927,930,933,936,939],{"class":168,"line":320},[166,928,929],{"class":202},"    if",[166,931,932],{"class":206}," idx ",[166,934,935],{"class":202},"==",[166,937,938],{"class":314}," 0",[166,940,941],{"class":206},":\n",[166,943,944,947,949,952],{"class":168,"line":335},[166,945,946],{"class":206},"        point.explosion ",[166,948,242],{"class":202},[166,950,951],{"class":314}," 12",[166,953,954],{"class":540},"          # pull the first slice out slightly\n",[166,956,957],{"class":168,"line":350},[166,958,959],{"class":206},"    series.data_points.append(point)\n",[166,961,962],{"class":168,"line":365},[166,963,233],{"emptyLinePlaceholder":232},[166,965,966,968,970],{"class":168,"line":371},[166,967,644],{"class":206},[166,969,647],{"class":176},[166,971,598],{"class":206},[10,973,974,976],{},[163,975,901],{}," is the zero-based position of the slice, matching the order of the data rows. Explosion is measured as a percentage of the radius — 10 to 15 reads as deliberate emphasis, while 40 makes the chart look broken.",[10,978,979],{},"Explode exactly one slice, or none. The moment two are pulled out, the reader loses the reference circle that made the proportions legible in the first place.",[23,981,32,986,32,989,32,992,32,995,32,1000,32,1006,32,1010,32,1014,32,1020,32,1025,32,1029,32,1032,32,1035,32,1039,32,1041,32,1044,32,1046,32,1050,32,1052,32,1055,32,1059,32,1062,32,1064,32,1069,32,1074,32,1078,32,1080,32,1082,32,1087,32,1091,32,1094,32,1100],{"viewBox":982,"role":26,"ariaLabelledBy":983,"xmlns":30,"style":31},"0 0 740 244",[984,985],"pie-ref-t","pie-ref-d",[34,987,988],{"id":984},"Why the two Reference ranges start on different rows",[38,990,991],{"id":985},"The values reference includes the header cell because titles_from_data takes the series name from it. The categories reference starts at the first data row, because the label list has no header. Starting both at the same row either consumes a data row as a title or turns the header into a category.",[42,993],{"x":44,"y":44,"width":45,"height":994,"fill":47},"244",[42,996],{"x":129,"y":997,"width":129,"height":998,"fill":999},"40","30","#1f4e78",[49,1001,1005],{"x":1002,"y":1003,"style":1004},"225","60","font-size:11px;font-weight:700;fill:#ffffff;text-anchor:middle","Category",[42,1007],{"x":1008,"y":997,"width":1009,"height":998,"fill":999},"300","130",[49,1011,1013],{"x":1012,"y":1003,"style":1004},"365","Revenue",[42,1015],{"x":129,"y":1016,"width":129,"height":1017,"fill":1018,"stroke":1019},"70","28","#ebebfd","var(--brand,#5b5cf0)",[49,1021,1024],{"x":1002,"y":1022,"style":1023},"89","font-size:11px;fill:var(--text,#172033);text-anchor:middle","Core products",[42,1026],{"x":1008,"y":1016,"width":1009,"height":1017,"fill":1027,"stroke":1028},"#d9f4f1","var(--teal,#0f9488)",[49,1030,1031],{"x":1012,"y":1022,"style":1023},"552,000",[42,1033],{"x":129,"y":1034,"width":129,"height":1017,"fill":1018,"stroke":1019},"98",[49,1036,1038],{"x":1002,"y":1037,"style":1023},"117","Services",[42,1040],{"x":1008,"y":1034,"width":1009,"height":1017,"fill":1027,"stroke":1028},[49,1042,1043],{"x":1012,"y":1037,"style":1023},"281,000",[42,1045],{"x":129,"y":76,"width":129,"height":1017,"fill":1018,"stroke":1019},[49,1047,1049],{"x":1002,"y":1048,"style":1023},"145","Support",[42,1051],{"x":1008,"y":76,"width":1009,"height":1017,"fill":1027,"stroke":1028},[49,1053,1054],{"x":1012,"y":1048,"style":1023},"96,000",[168,1056],{"x1":1057,"y1":1016,"x2":1003,"y2":1016,"stroke":1019,"style":1058},"146","stroke-width:1.5px",[168,1060],{"x1":1057,"y1":1061,"x2":1003,"y2":1061,"stroke":1019,"style":1058},"154",[168,1063],{"x1":1003,"y1":1016,"x2":1003,"y2":1061,"stroke":1019,"style":1058},[49,1065,668],{"x":1066,"y":1067,"style":1068},"68","106","font-size:11px;font-weight:700;fill:var(--brand-strong,#4338ca)",[49,1070,1073],{"x":1066,"y":1071,"style":1072},"124","font-size:11px;fill:var(--muted,#5b6780)","min_row=2",[168,1075],{"x1":1076,"y1":997,"x2":1077,"y2":997,"stroke":1028,"style":1058},"434","520",[168,1079],{"x1":1076,"y1":1061,"x2":1077,"y2":1061,"stroke":1028,"style":1058},[168,1081],{"x1":1077,"y1":997,"x2":1077,"y2":1061,"stroke":1028,"style":1058},[49,1083,660],{"x":1084,"y":1085,"style":1086},"532","90","font-size:11px;font-weight:700;fill:var(--teal-ink,#0b6157)",[49,1088,1090],{"x":1084,"y":1089,"style":1072},"110","min_row=1",[49,1092,664],{"x":1084,"y":1093,"style":1072},"128",[49,1095,1099],{"x":1096,"y":1097,"style":1098},"370","196","font-size:11.5px;fill:var(--text,#172033);text-anchor:middle","Start both at row 1 and \"Category\" becomes a slice.",[49,1101,1103],{"x":1096,"y":1102,"style":1098},"220","Start both at row 2 and the series is named \"552000\".",[151,1105,1107],{"id":1106},"step-4b-group-the-tail-before-you-chart-it","Step 4b: Group the tail before you chart it",[10,1109,1110],{},"The commonest reason a generated pie is unreadable is that nobody decided how many slices it should have — the chart simply plots whatever the query returned, and a category list that grows from four to fourteen over a year turns a clear picture into a colour wheel. Deciding the cut in code keeps it stable:",[156,1112,1114],{"className":193,"code":1113,"language":195,"meta":161,"style":161},"import pandas as pd\n\n\ndef top_n_with_other(frame, label_col, value_col, n=4, other=\"Other\"):\n    \"\"\"Keep the largest n categories; roll everything else into one row.\"\"\"\n    ranked = frame.sort_values(value_col, ascending=False).reset_index(drop=True)\n    if len(ranked) \u003C= n + 1:\n        return ranked\n    head = ranked.iloc[:n]\n    tail_total = ranked.iloc[n:][value_col].sum()\n    tail = pd.DataFrame({label_col: [other], value_col: [tail_total]})\n    return pd.concat([head, tail], ignore_index=True)\n",[163,1115,1116,1129,1133,1137,1164,1169,1199,1223,1231,1241,1251,1261],{"__ignoreMap":161},[166,1117,1118,1120,1123,1126],{"class":168,"line":169},[166,1119,210],{"class":202},[166,1121,1122],{"class":206}," pandas ",[166,1124,1125],{"class":202},"as",[166,1127,1128],{"class":206}," pd\n",[166,1130,1131],{"class":168,"line":216},[166,1132,233],{"emptyLinePlaceholder":232},[166,1134,1135],{"class":168,"line":229},[166,1136,233],{"emptyLinePlaceholder":232},[166,1138,1139,1142,1146,1149,1151,1154,1157,1159,1162],{"class":168,"line":236},[166,1140,1141],{"class":202},"def",[166,1143,1145],{"class":1144},"s_Opv"," top_n_with_other",[166,1147,1148],{"class":206},"(frame, label_col, value_col, n",[166,1150,242],{"class":202},[166,1152,1153],{"class":314},"4",[166,1155,1156],{"class":206},", other",[166,1158,242],{"class":202},[166,1160,1161],{"class":176},"\"Other\"",[166,1163,888],{"class":206},[166,1165,1166],{"class":168,"line":248},[166,1167,1168],{"class":176},"    \"\"\"Keep the largest n categories; roll everything else into one row.\"\"\"\n",[166,1170,1171,1174,1176,1179,1182,1184,1187,1190,1193,1195,1197],{"class":168,"line":259},[166,1172,1173],{"class":206},"    ranked ",[166,1175,242],{"class":202},[166,1177,1178],{"class":206}," frame.sort_values(value_col, ",[166,1180,1181],{"class":510},"ascending",[166,1183,242],{"class":202},[166,1185,1186],{"class":314},"False",[166,1188,1189],{"class":206},").reset_index(",[166,1191,1192],{"class":510},"drop",[166,1194,242],{"class":202},[166,1196,595],{"class":314},[166,1198,598],{"class":206},[166,1200,1201,1203,1206,1209,1212,1215,1218,1221],{"class":168,"line":270},[166,1202,929],{"class":202},[166,1204,1205],{"class":314}," len",[166,1207,1208],{"class":206},"(ranked) ",[166,1210,1211],{"class":202},"\u003C=",[166,1213,1214],{"class":206}," n ",[166,1216,1217],{"class":202},"+",[166,1219,1220],{"class":314}," 1",[166,1222,941],{"class":206},[166,1224,1225,1228],{"class":168,"line":275},[166,1226,1227],{"class":202},"        return",[166,1229,1230],{"class":206}," ranked\n",[166,1232,1233,1236,1238],{"class":168,"line":286},[166,1234,1235],{"class":206},"    head ",[166,1237,242],{"class":202},[166,1239,1240],{"class":206}," ranked.iloc[:n]\n",[166,1242,1243,1246,1248],{"class":168,"line":304},[166,1244,1245],{"class":206},"    tail_total ",[166,1247,242],{"class":202},[166,1249,1250],{"class":206}," ranked.iloc[n:][value_col].sum()\n",[166,1252,1253,1256,1258],{"class":168,"line":320},[166,1254,1255],{"class":206},"    tail ",[166,1257,242],{"class":202},[166,1259,1260],{"class":206}," pd.DataFrame({label_col: [other], value_col: [tail_total]})\n",[166,1262,1263,1266,1269,1272,1274,1276],{"class":168,"line":335},[166,1264,1265],{"class":202},"    return",[166,1267,1268],{"class":206}," pd.concat([head, tail], ",[166,1270,1271],{"class":510},"ignore_index",[166,1273,242],{"class":202},[166,1275,595],{"class":314},[166,1277,598],{"class":206},[23,1279,32,1284,32,1287,32,1290,32,1292,32,1295,32,1301,32,1304,32,1307,32,1312,32,1317,32,1320,32,1323,32,1326,32,1330,32,1333,32,1336,32,1339,32,1342,32,1344,32,1347,32,1352],{"viewBox":1280,"role":26,"ariaLabelledBy":1281,"xmlns":30,"style":31},"0 0 740 214",[1282,1283],"pie-tail-t","pie-tail-d",[34,1285,1286],{"id":1282},"Rolling the long tail into a single Other slice",[38,1288,1289],{"id":1283},"Eleven categories produce seven slices below three percent each, which are too thin to see and too many to label. Keeping the largest four and summing the rest into one Other slice preserves the total exactly while leaving five readable segments.",[42,1291],{"x":44,"y":44,"width":45,"height":84,"fill":47},[49,1293,1294],{"x":51,"y":52,"style":90},"eleven categories as written",[42,1296],{"x":997,"y":1297,"width":1298,"height":1299,"rx":1300,"fill":59},"52","288","18","3",[42,1302],{"x":997,"y":1303,"width":96,"height":1299,"rx":1300,"fill":63},"74",[42,1305],{"x":997,"y":71,"width":71,"height":1299,"rx":1300,"fill":1306},"#8a5808",[42,1308],{"x":997,"y":1309,"width":1310,"height":1299,"rx":1300,"fill":1311},"118","62","#d81b73",[42,1313],{"x":997,"y":135,"width":1314,"height":1315,"rx":98,"fill":1316},"20","6","#5b6780",[42,1318],{"x":997,"y":129,"width":1319,"height":1315,"rx":98,"fill":1316},"17",[42,1321],{"x":997,"y":1322,"width":97,"height":1315,"rx":98,"fill":1316},"160",[42,1324],{"x":997,"y":108,"width":1325,"height":1315,"rx":98,"fill":1316},"11",[49,1327,1329],{"x":51,"y":1328,"style":85},"198","seven slivers under 3% each — unlabellable",[49,1331,1332],{"x":89,"y":52,"style":53},"top four plus Other",[42,1334],{"x":1335,"y":1297,"width":1298,"height":1299,"rx":1300,"fill":59},"412",[42,1337],{"x":1335,"y":1338,"width":96,"height":1299,"rx":1300,"fill":63},"80",[42,1340],{"x":1335,"y":1341,"width":71,"height":1299,"rx":1300,"fill":1306},"108",[42,1343],{"x":1335,"y":128,"width":1310,"height":1299,"rx":1300,"fill":1311},[42,1345],{"x":1335,"y":115,"width":1346,"height":1299,"rx":1300,"fill":1316},"72",[49,1348,1351],{"x":1349,"y":1350,"style":103},"500","178","Other",[49,1353,1355],{"x":89,"y":1354,"style":85},"200","five readable segments, and the total is unchanged",[10,1357,1358],{},"Summing rather than dropping the tail is the part that matters: a pie whose slices do not add to the reported total is worse than one with too many slices, because the percentages Excel computes are shares of what was plotted. Name the rolled-up slice for what it is — \"Other (7 categories)\" is more honest than a bare \"Other\", and it tells the reader there is detail to ask for.",[151,1360,1362],{"id":1361},"step-5-the-doughnut-variant","Step 5: The doughnut variant",[10,1364,1365],{},"A doughnut is the same data with a hole, and openpyxl exposes it as its own class:",[156,1367,1369],{"className":193,"code":1368,"language":195,"meta":161,"style":161},"from openpyxl.chart import DoughnutChart\n\ndonut = DoughnutChart(holeSize=55)\ndonut.title = \"Revenue mix\"\ndonut.add_data(data, titles_from_data=True)\ndonut.set_categories(labels)\ndonut.dataLabels = DataLabelList()\ndonut.dataLabels.showPercent = True\nws.add_chart(donut, \"D22\")\nwb.save(\"pie.xlsx\")\n",[163,1370,1371,1382,1386,1406,1416,1429,1434,1443,1452,1462],{"__ignoreMap":161},[166,1372,1373,1375,1377,1379],{"class":168,"line":169},[166,1374,203],{"class":202},[166,1376,221],{"class":206},[166,1378,210],{"class":202},[166,1380,1381],{"class":206}," DoughnutChart\n",[166,1383,1384],{"class":168,"line":216},[166,1385,233],{"emptyLinePlaceholder":232},[166,1387,1388,1391,1393,1396,1399,1401,1404],{"class":168,"line":229},[166,1389,1390],{"class":206},"donut ",[166,1392,242],{"class":202},[166,1394,1395],{"class":206}," DoughnutChart(",[166,1397,1398],{"class":510},"holeSize",[166,1400,242],{"class":202},[166,1402,1403],{"class":314},"55",[166,1405,598],{"class":206},[166,1407,1408,1411,1413],{"class":168,"line":236},[166,1409,1410],{"class":206},"donut.title ",[166,1412,242],{"class":202},[166,1414,1415],{"class":176}," \"Revenue mix\"\n",[166,1417,1418,1421,1423,1425,1427],{"class":168,"line":248},[166,1419,1420],{"class":206},"donut.add_data(data, ",[166,1422,590],{"class":510},[166,1424,242],{"class":202},[166,1426,595],{"class":314},[166,1428,598],{"class":206},[166,1430,1431],{"class":168,"line":259},[166,1432,1433],{"class":206},"donut.set_categories(labels)\n",[166,1435,1436,1439,1441],{"class":168,"line":270},[166,1437,1438],{"class":206},"donut.dataLabels ",[166,1440,242],{"class":202},[166,1442,717],{"class":206},[166,1444,1445,1448,1450],{"class":168,"line":275},[166,1446,1447],{"class":206},"donut.dataLabels.showPercent ",[166,1449,242],{"class":202},[166,1451,727],{"class":314},[166,1453,1454,1457,1460],{"class":168,"line":286},[166,1455,1456],{"class":206},"ws.add_chart(donut, ",[166,1458,1459],{"class":176},"\"D22\"",[166,1461,598],{"class":206},[166,1463,1464,1466,1468],{"class":168,"line":304},[166,1465,644],{"class":206},[166,1467,647],{"class":176},[166,1469,598],{"class":206},[10,1471,1472],{},"The hole gives you space for a headline number in a dashboard, but it also removes the wedge angles at the centre, which is where the proportion is easiest to judge. A doughnut is the weaker chart of the two for reading proportions and the better one for a dashboard tile; choose on that basis rather than on appearance.",[151,1474,1476],{"id":1475},"common-pitfalls-and-gotchas","Common pitfalls and gotchas",[1478,1479,1480,1496],"table",{},[1481,1482,1483],"thead",{},[1484,1485,1486,1490,1493],"tr",{},[1487,1488,1489],"th",{},"Symptom",[1487,1491,1492],{},"Cause",[1487,1494,1495],{},"Fix",[1497,1498,1499,1514,1527,1542,1562,1573,1591,1602],"tbody",{},[1484,1500,1501,1505,1511],{},[1502,1503,1504],"td",{},"Only one slice appears",[1502,1506,1507,1508,1510],{},"Values ",[163,1509,655],{}," covers a single cell",[1502,1512,1513],{},"Span every data row",[1484,1515,1516,1519,1522],{},[1502,1517,1518],{},"A slice labelled \"Category\"",[1502,1520,1521],{},"Categories reference included the header",[1502,1523,1524,1525],{},"Start categories at ",[163,1526,1073],{},[1484,1528,1529,1532,1537],{},[1502,1530,1531],{},"Series named \"552000\"",[1502,1533,1534,1535],{},"Values reference excluded the header with ",[163,1536,664],{},[1502,1538,1539,1540],{},"Start values at ",[163,1541,1090],{},[1484,1543,1544,1547,1553],{},[1502,1545,1546],{},"Labels show raw values",[1502,1548,1549,1552],{},[163,1550,1551],{},"showPercent"," not set",[1502,1554,1555,1558,1559],{},[163,1556,1557],{},"DataLabelList()"," with ",[163,1560,1561],{},"showPercent=True",[1484,1563,1564,1567,1570],{},[1502,1565,1566],{},"Percentages do not total 100",[1502,1568,1569],{},"Pre-computed and rounded in pandas",[1502,1571,1572],{},"Let Excel compute them from values",[1484,1574,1575,1578,1585],{},[1502,1576,1577],{},"Every slice is the default blue",[1502,1579,1580,1581,1584],{},"No ",[163,1582,1583],{},"data_points"," assigned",[1502,1586,1587,1588,1590],{},"One ",[163,1589,775],{}," per slice with a fill",[1484,1592,1593,1596,1599],{},[1502,1594,1595],{},"Chart covers the data",[1502,1597,1598],{},"Anchored inside the table",[1502,1600,1601],{},"Anchor to the right of the last column",[1484,1603,1604,1607,1610],{},[1502,1605,1606],{},"Twelve unreadable slivers",[1502,1608,1609],{},"Too many categories",[1502,1611,1612],{},"Group the tail into \"Other\"",[151,1614,1616],{"id":1615},"performance-and-scale-notes","Performance and scale notes",[10,1618,1619],{},"A pie chart is a few kilobytes in the file regardless of the values behind it, so the cost is never the chart. The scale question is the number of categories, and it is a design limit rather than a technical one: past six slices the chart stops being readable long before anything gets slow.",[10,1621,1622,1623,1627],{},"When a report needs the same breakdown for many groups — one pie per region, say — resist a grid of twelve pies. A single grouped or stacked bar chart shows all of them at once and lets the reader compare across groups, which a row of pies cannot. ",[17,1624,1626],{"href":1625},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl\u002F","Create a Bar Chart in Excel with openpyxl"," covers that shape.",[151,1629,1631],{"id":1630},"conclusion","Conclusion",[10,1633,1634,1635,1637,1638,1640,1641,1643],{},"Build the pie from two ",[163,1636,655],{}," ranges that deliberately start on different rows — values from the header with ",[163,1639,664],{},", categories from the first data row — and let Excel compute the percentage labels so they always add to 100. Colour the slices explicitly with ",[163,1642,775],{}," objects, explode at most one, and group the long tail into \"Other\" before charting. Then check the shape of the data: three or four uneven parts make a good pie, and everything else makes a better bar chart.",[151,1645,1647],{"id":1646},"frequently-asked-questions","Frequently asked questions",[10,1649,1650,1654,1655,1657,1658,1660,1661,1663,1664,1666,1667,21],{},[1651,1652,1653],"strong",{},"Why does my pie chart only show one slice?","\nThe values ",[163,1656,655],{}," included the header row while ",[163,1659,590],{}," was not set, or it covered a single cell. Check that the ",[163,1662,655],{}," spans every data row and that ",[163,1665,520],{}," is the header when ",[163,1668,664],{},[10,1670,1671,1674,1675,1558,1678,1680],{},[1651,1672,1673],{},"How do I show percentages instead of raw values?","\nAttach a ",[163,1676,1677],{},"DataLabelList",[163,1679,1561],{},". Excel computes the percentages from the plotted values, so they always add to 100 even when the underlying numbers are rounded.",[10,1682,1683,1686,1687,1689,1690,1693,1694,1697],{},[1651,1684,1685],{},"Can I set the colour of an individual slice?","\nYes. Assign a ",[163,1688,775],{}," with a ",[163,1691,1692],{},"GraphicalProperties"," fill to ",[163,1695,1696],{},"series.data_points",", one per slice you want to control.",[10,1699,1700,1703],{},[1651,1701,1702],{},"When should I not use a pie chart?","\nWhen there are more than five or six categories, when two shares are close, or when the reader needs to compare across periods. A bar chart is easier to read in all three cases.",[151,1705,1707],{"id":1706},"related","Related",[10,1709,1710],{},"Up to the parent guide:",[1712,1713,1714],"ul",{},[1715,1716,1717,1719],"li",{},[17,1718,20],{"href":19}," — chart types, references and anchoring.",[10,1721,1722],{},"Related guides:",[1712,1724,1725,1730,1737,1744],{},[1715,1726,1727,1729],{},[17,1728,1626],{"href":1625}," — the chart most pies should have been.",[1715,1731,1732,1736],{},[17,1733,1735],{"href":1734},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python\u002F","Add a Line Chart to an Excel Report with Python"," — for anything that moves over time.",[1715,1738,1739,1743],{},[17,1740,1742],{"href":1741},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fadd-a-chart-to-an-excel-file-with-xlsxwriter\u002F","Add a Chart to an Excel File with xlsxwriter"," — the same charts on the write-only engine.",[1715,1745,1746,1750],{},[17,1747,1749],{"href":1748},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-summary-sheet-to-excel-report-python\u002F","Add a Summary Sheet to an Excel Report in Python"," — where a mix chart usually belongs.",[1752,1753,1754],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":161,"searchDepth":216,"depth":216,"links":1756},[1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768],{"id":153,"depth":216,"text":154},{"id":186,"depth":216,"text":187},{"id":467,"depth":216,"text":468},{"id":682,"depth":216,"text":683},{"id":768,"depth":216,"text":769},{"id":1106,"depth":216,"text":1107},{"id":1361,"depth":216,"text":1362},{"id":1475,"depth":216,"text":1476},{"id":1615,"depth":216,"text":1616},{"id":1630,"depth":216,"text":1631},{"id":1646,"depth":216,"text":1647},{"id":1706,"depth":216,"text":1707},"2026-08-11","PieChart, data labels that show percentages, exploding a slice, a doughnut variant — and the honest guidance on when a bar chart tells the same story better.","md",[1773,1775,1777,1779],{"q":1653,"a":1774},"The values Reference included the header row while titles_from_data was not set, or it covered a single cell. Check that the Reference spans every data row and that min_row is the header when titles_from_data=True.",{"q":1673,"a":1776},"Attach a DataLabelList with showPercent=True. Excel computes the percentages from the plotted values, so they always add to 100 even when the underlying numbers are rounded.",{"q":1685,"a":1778},"Yes. Assign a DataPoint with a GraphicalProperties fill to series.data_points, one per slice you want to control.",{"q":1702,"a":1780},"When there are more than five or six categories, when two shares are close, or when the reader needs to compare across periods. A bar chart is easier to read in all three cases.",{"breadcrumb":1782},[1783,1786,1789,1790],{"name":1784,"item":1785},"Home","\u002F",{"name":1787,"item":1788},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":20,"item":19},{"name":5,"item":1791},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-pie-chart-in-excel-with-openpyxl\u002F","\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-pie-chart-in-excel-with-openpyxl",{"title":5,"description":1794},"Build Excel pie and doughnut charts from Python with openpyxl — Reference ranges, percentage data labels, slice colours, exploding a segment, and when to use a bar chart instead.","create-a-pie-chart-in-excel-with-openpyxl","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-pie-chart-in-excel-with-openpyxl\u002Findex","how-to","XjW_dL3reBx2ut3B-Nq7SQnMW32Z72SCCDg8HaruHXo",[1800,1803],{"title":1735,"path":1801,"stem":1802,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python\u002Findex",{"title":1626,"path":1804,"stem":1805,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl\u002Findex",1786800028826]