[{"data":1,"prerenderedAt":1444},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl":1436},{"id":4,"title":5,"body":6,"description":1428,"extension":1429,"meta":1430,"navigation":111,"path":1431,"seo":1432,"stem":1434,"__hash__":1435},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl\u002Findex.md","Create a Bar Chart in Excel with openpyxl",{"type":7,"value":8,"toc":1416},"minimark",[9,32,37,62,69,73,76,271,277,281,295,546,559,563,575,813,829,833,840,1131,1138,1142,1278,1282,1289,1293,1310,1335,1350,1367,1371,1385,1389,1412],[10,11,12,13,17,18,21,22,25,26,31],"p",{},"This page builds one thing end to end: a vertical bar chart written into an ",[14,15,16],"code",{},".xlsx"," file with openpyxl, fully editable when you open it in Excel. You will write a small category\u002Fvalue table, bind it to a ",[14,19,20],{},"BarChart"," with ",[14,23,24],{},"Reference",", attach category labels, label the axes, apply a style, and anchor the chart to a cell. It is the focused walkthrough for the parent cluster, ",[27,28,30],"a",{"href":29},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002F","Creating Charts in Excel with openpyxl",", which covers the chart model the steps below assume.",[33,34,36],"h2",{"id":35},"prerequisites","Prerequisites",[38,39,44],"pre",{"className":40,"code":41,"language":42,"meta":43,"style":43},"language-bash shiki shiki-themes github-light github-dark","pip install openpyxl\n","bash","",[14,45,46],{"__ignoreMap":43},[47,48,51,55,59],"span",{"class":49,"line":50},"line",1,[47,52,54],{"class":53},"sScJk","pip",[47,56,58],{"class":57},"sZZnC"," install",[47,60,61],{"class":57}," openpyxl\n",[10,63,64,65,68],{},"openpyxl 2.5+ has the modern ",[14,66,67],{},"openpyxl.chart"," API used here; any current release works. No other dependencies — the data is generated inline.",[33,70,72],{"id":71},"step-1-write-sample-categoryvalue-data","Step 1 — Write sample category\u002Fvalue data",[10,74,75],{},"A bar chart needs two columns: a category label and a numeric value. Put a header in row 1 so the series can take its name from it.",[38,77,81],{"className":78,"code":79,"language":80,"meta":43,"style":43},"language-python shiki shiki-themes github-light github-dark","# pip install openpyxl\nfrom openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.title = \"Sales\"\n\nws.append([\"Product\", \"Units Sold\"])          # row 1: header\nfor row in [(\"Widget\", 340), (\"Gadget\", 280), (\"Gizmo\", 410), (\"Doohickey\", 195)]:\n    ws.append(row)                              # rows 2-5: data\n\nwb.save(\"bar_step1.xlsx\")\nprint(\"Data written: 4 products in rows 2-5, header in row 1\")\n","python",[14,82,83,89,106,113,125,136,147,152,173,231,240,245,257],{"__ignoreMap":43},[47,84,85],{"class":49,"line":50},[47,86,88],{"class":87},"sJ8bj","# pip install openpyxl\n",[47,90,92,96,100,103],{"class":49,"line":91},2,[47,93,95],{"class":94},"szBVR","from",[47,97,99],{"class":98},"sVt8B"," openpyxl ",[47,101,102],{"class":94},"import",[47,104,105],{"class":98}," Workbook\n",[47,107,109],{"class":49,"line":108},3,[47,110,112],{"emptyLinePlaceholder":111},true,"\n",[47,114,116,119,122],{"class":49,"line":115},4,[47,117,118],{"class":98},"wb ",[47,120,121],{"class":94},"=",[47,123,124],{"class":98}," Workbook()\n",[47,126,128,131,133],{"class":49,"line":127},5,[47,129,130],{"class":98},"ws ",[47,132,121],{"class":94},[47,134,135],{"class":98}," wb.active\n",[47,137,139,142,144],{"class":49,"line":138},6,[47,140,141],{"class":98},"ws.title ",[47,143,121],{"class":94},[47,145,146],{"class":57}," \"Sales\"\n",[47,148,150],{"class":49,"line":149},7,[47,151,112],{"emptyLinePlaceholder":111},[47,153,155,158,161,164,167,170],{"class":49,"line":154},8,[47,156,157],{"class":98},"ws.append([",[47,159,160],{"class":57},"\"Product\"",[47,162,163],{"class":98},", ",[47,165,166],{"class":57},"\"Units Sold\"",[47,168,169],{"class":98},"])          ",[47,171,172],{"class":87},"# row 1: header\n",[47,174,176,179,182,185,188,191,193,197,200,203,205,208,210,213,215,218,220,223,225,228],{"class":49,"line":175},9,[47,177,178],{"class":94},"for",[47,180,181],{"class":98}," row ",[47,183,184],{"class":94},"in",[47,186,187],{"class":98}," [(",[47,189,190],{"class":57},"\"Widget\"",[47,192,163],{"class":98},[47,194,196],{"class":195},"sj4cs","340",[47,198,199],{"class":98},"), (",[47,201,202],{"class":57},"\"Gadget\"",[47,204,163],{"class":98},[47,206,207],{"class":195},"280",[47,209,199],{"class":98},[47,211,212],{"class":57},"\"Gizmo\"",[47,214,163],{"class":98},[47,216,217],{"class":195},"410",[47,219,199],{"class":98},[47,221,222],{"class":57},"\"Doohickey\"",[47,224,163],{"class":98},[47,226,227],{"class":195},"195",[47,229,230],{"class":98},")]:\n",[47,232,234,237],{"class":49,"line":233},10,[47,235,236],{"class":98},"    ws.append(row)                              ",[47,238,239],{"class":87},"# rows 2-5: data\n",[47,241,243],{"class":49,"line":242},11,[47,244,112],{"emptyLinePlaceholder":111},[47,246,248,251,254],{"class":49,"line":247},12,[47,249,250],{"class":98},"wb.save(",[47,252,253],{"class":57},"\"bar_step1.xlsx\"",[47,255,256],{"class":98},")\n",[47,258,260,263,266,269],{"class":49,"line":259},13,[47,261,262],{"class":195},"print",[47,264,265],{"class":98},"(",[47,267,268],{"class":57},"\"Data written: 4 products in rows 2-5, header in row 1\"",[47,270,256],{"class":98},[10,272,273,274,276],{},"The data now occupies columns A and B, rows 1 through 5. Hold that layout in mind — every ",[14,275,24],{}," below refers to it.",[33,278,280],{"id":279},"step-2-build-the-barchart-and-bind-the-values","Step 2 — Build the BarChart and bind the values",[10,282,283,284,286,287,290,291,294],{},"Create the chart, then build a ",[14,285,24],{}," for the value column. Include the header row (",[14,288,289],{},"min_row=1",") and pass ",[14,292,293],{},"titles_from_data=True"," so the series is named \"Units Sold\" from cell B1.",[38,296,298],{"className":78,"code":297,"language":80,"meta":43,"style":43},"# pip install openpyxl\nfrom openpyxl import Workbook\nfrom openpyxl.chart import BarChart, Reference\n\nwb = Workbook()\nws = wb.active\nws.append([\"Product\", \"Units Sold\"])\nfor row in [(\"Widget\", 340), (\"Gadget\", 280), (\"Gizmo\", 410), (\"Doohickey\", 195)]:\n    ws.append(row)\n\nchart = BarChart()\nchart.type = \"col\"   # \"col\" = vertical bars; \"bar\" = horizontal\n\n# Value range: column B, header (row 1) through last data row (row 5).\ndata = Reference(ws, min_col=2, min_row=1, max_row=5)\nchart.add_data(data, titles_from_data=True)\n\nprint(\"series:\", len(chart.series), \"| name:\", chart.series[0].tx.strRef.f)\nwb.save(\"bar_step2.xlsx\")\n",[14,299,300,304,314,326,330,338,346,359,401,406,410,420,433,437,443,485,501,506,536],{"__ignoreMap":43},[47,301,302],{"class":49,"line":50},[47,303,88],{"class":87},[47,305,306,308,310,312],{"class":49,"line":91},[47,307,95],{"class":94},[47,309,99],{"class":98},[47,311,102],{"class":94},[47,313,105],{"class":98},[47,315,316,318,321,323],{"class":49,"line":108},[47,317,95],{"class":94},[47,319,320],{"class":98}," openpyxl.chart ",[47,322,102],{"class":94},[47,324,325],{"class":98}," BarChart, Reference\n",[47,327,328],{"class":49,"line":115},[47,329,112],{"emptyLinePlaceholder":111},[47,331,332,334,336],{"class":49,"line":127},[47,333,118],{"class":98},[47,335,121],{"class":94},[47,337,124],{"class":98},[47,339,340,342,344],{"class":49,"line":138},[47,341,130],{"class":98},[47,343,121],{"class":94},[47,345,135],{"class":98},[47,347,348,350,352,354,356],{"class":49,"line":149},[47,349,157],{"class":98},[47,351,160],{"class":57},[47,353,163],{"class":98},[47,355,166],{"class":57},[47,357,358],{"class":98},"])\n",[47,360,361,363,365,367,369,371,373,375,377,379,381,383,385,387,389,391,393,395,397,399],{"class":49,"line":154},[47,362,178],{"class":94},[47,364,181],{"class":98},[47,366,184],{"class":94},[47,368,187],{"class":98},[47,370,190],{"class":57},[47,372,163],{"class":98},[47,374,196],{"class":195},[47,376,199],{"class":98},[47,378,202],{"class":57},[47,380,163],{"class":98},[47,382,207],{"class":195},[47,384,199],{"class":98},[47,386,212],{"class":57},[47,388,163],{"class":98},[47,390,217],{"class":195},[47,392,199],{"class":98},[47,394,222],{"class":57},[47,396,163],{"class":98},[47,398,227],{"class":195},[47,400,230],{"class":98},[47,402,403],{"class":49,"line":175},[47,404,405],{"class":98},"    ws.append(row)\n",[47,407,408],{"class":49,"line":233},[47,409,112],{"emptyLinePlaceholder":111},[47,411,412,415,417],{"class":49,"line":242},[47,413,414],{"class":98},"chart ",[47,416,121],{"class":94},[47,418,419],{"class":98}," BarChart()\n",[47,421,422,425,427,430],{"class":49,"line":247},[47,423,424],{"class":98},"chart.type ",[47,426,121],{"class":94},[47,428,429],{"class":57}," \"col\"",[47,431,432],{"class":87},"   # \"col\" = vertical bars; \"bar\" = horizontal\n",[47,434,435],{"class":49,"line":259},[47,436,112],{"emptyLinePlaceholder":111},[47,438,440],{"class":49,"line":439},14,[47,441,442],{"class":87},"# Value range: column B, header (row 1) through last data row (row 5).\n",[47,444,446,449,451,454,458,460,463,465,468,470,473,475,478,480,483],{"class":49,"line":445},15,[47,447,448],{"class":98},"data ",[47,450,121],{"class":94},[47,452,453],{"class":98}," Reference(ws, ",[47,455,457],{"class":456},"s4XuR","min_col",[47,459,121],{"class":94},[47,461,462],{"class":195},"2",[47,464,163],{"class":98},[47,466,467],{"class":456},"min_row",[47,469,121],{"class":94},[47,471,472],{"class":195},"1",[47,474,163],{"class":98},[47,476,477],{"class":456},"max_row",[47,479,121],{"class":94},[47,481,482],{"class":195},"5",[47,484,256],{"class":98},[47,486,488,491,494,496,499],{"class":49,"line":487},16,[47,489,490],{"class":98},"chart.add_data(data, ",[47,492,493],{"class":456},"titles_from_data",[47,495,121],{"class":94},[47,497,498],{"class":195},"True",[47,500,256],{"class":98},[47,502,504],{"class":49,"line":503},17,[47,505,112],{"emptyLinePlaceholder":111},[47,507,509,511,513,516,518,521,524,527,530,533],{"class":49,"line":508},18,[47,510,262],{"class":195},[47,512,265],{"class":98},[47,514,515],{"class":57},"\"series:\"",[47,517,163],{"class":98},[47,519,520],{"class":195},"len",[47,522,523],{"class":98},"(chart.series), ",[47,525,526],{"class":57},"\"| name:\"",[47,528,529],{"class":98},", chart.series[",[47,531,532],{"class":195},"0",[47,534,535],{"class":98},"].tx.strRef.f)\n",[47,537,539,541,544],{"class":49,"line":538},19,[47,540,250],{"class":98},[47,542,543],{"class":57},"\"bar_step2.xlsx\"",[47,545,256],{"class":98},[10,547,548,550,551,554,555,558],{},[14,549,293],{}," is what reads B1; drop it and the series is named \"Series 1\" instead. Pass ",[14,552,553],{},"from_rows=True"," to ",[14,556,557],{},"add_data"," only if your series run across rows rather than down columns — for this column layout, leave it off.",[33,560,562],{"id":561},"step-3-set-the-category-labels","Step 3 — Set the category labels",[10,564,565,566,569,570,574],{},"Without categories, the x-axis is labeled 1, 2, 3, 4. Bind the ",[14,567,568],{},"Product"," column — and ",[571,572,573],"strong",{},"exclude"," the header, because the header is a column title, not a category.",[38,576,578],{"className":78,"code":577,"language":80,"meta":43,"style":43},"# pip install openpyxl\nfrom openpyxl import Workbook\nfrom openpyxl.chart import BarChart, Reference\n\nwb = Workbook()\nws = wb.active\nws.append([\"Product\", \"Units Sold\"])\nfor row in [(\"Widget\", 340), (\"Gadget\", 280), (\"Gizmo\", 410), (\"Doohickey\", 195)]:\n    ws.append(row)\n\nchart = BarChart()\nchart.type = \"col\"\nchart.add_data(Reference(ws, min_col=2, min_row=1, max_row=5), titles_from_data=True)\n\n# Category range: column A, data rows only (2-5) — NOT the header.\ncats = Reference(ws, min_col=1, min_row=2, max_row=5)\nchart.set_categories(cats)\n\nwb.save(\"bar_step3.xlsx\")\nprint(\"Categories bound to A2:A5 (Widget, Gadget, Gizmo, Doohickey)\")\n",[14,579,580,584,594,604,608,616,624,636,678,682,686,694,703,741,745,750,783,788,792,801],{"__ignoreMap":43},[47,581,582],{"class":49,"line":50},[47,583,88],{"class":87},[47,585,586,588,590,592],{"class":49,"line":91},[47,587,95],{"class":94},[47,589,99],{"class":98},[47,591,102],{"class":94},[47,593,105],{"class":98},[47,595,596,598,600,602],{"class":49,"line":108},[47,597,95],{"class":94},[47,599,320],{"class":98},[47,601,102],{"class":94},[47,603,325],{"class":98},[47,605,606],{"class":49,"line":115},[47,607,112],{"emptyLinePlaceholder":111},[47,609,610,612,614],{"class":49,"line":127},[47,611,118],{"class":98},[47,613,121],{"class":94},[47,615,124],{"class":98},[47,617,618,620,622],{"class":49,"line":138},[47,619,130],{"class":98},[47,621,121],{"class":94},[47,623,135],{"class":98},[47,625,626,628,630,632,634],{"class":49,"line":149},[47,627,157],{"class":98},[47,629,160],{"class":57},[47,631,163],{"class":98},[47,633,166],{"class":57},[47,635,358],{"class":98},[47,637,638,640,642,644,646,648,650,652,654,656,658,660,662,664,666,668,670,672,674,676],{"class":49,"line":154},[47,639,178],{"class":94},[47,641,181],{"class":98},[47,643,184],{"class":94},[47,645,187],{"class":98},[47,647,190],{"class":57},[47,649,163],{"class":98},[47,651,196],{"class":195},[47,653,199],{"class":98},[47,655,202],{"class":57},[47,657,163],{"class":98},[47,659,207],{"class":195},[47,661,199],{"class":98},[47,663,212],{"class":57},[47,665,163],{"class":98},[47,667,217],{"class":195},[47,669,199],{"class":98},[47,671,222],{"class":57},[47,673,163],{"class":98},[47,675,227],{"class":195},[47,677,230],{"class":98},[47,679,680],{"class":49,"line":175},[47,681,405],{"class":98},[47,683,684],{"class":49,"line":233},[47,685,112],{"emptyLinePlaceholder":111},[47,687,688,690,692],{"class":49,"line":242},[47,689,414],{"class":98},[47,691,121],{"class":94},[47,693,419],{"class":98},[47,695,696,698,700],{"class":49,"line":247},[47,697,424],{"class":98},[47,699,121],{"class":94},[47,701,702],{"class":57}," \"col\"\n",[47,704,705,708,710,712,714,716,718,720,722,724,726,728,730,733,735,737,739],{"class":49,"line":259},[47,706,707],{"class":98},"chart.add_data(Reference(ws, ",[47,709,457],{"class":456},[47,711,121],{"class":94},[47,713,462],{"class":195},[47,715,163],{"class":98},[47,717,467],{"class":456},[47,719,121],{"class":94},[47,721,472],{"class":195},[47,723,163],{"class":98},[47,725,477],{"class":456},[47,727,121],{"class":94},[47,729,482],{"class":195},[47,731,732],{"class":98},"), ",[47,734,493],{"class":456},[47,736,121],{"class":94},[47,738,498],{"class":195},[47,740,256],{"class":98},[47,742,743],{"class":49,"line":439},[47,744,112],{"emptyLinePlaceholder":111},[47,746,747],{"class":49,"line":445},[47,748,749],{"class":87},"# Category range: column A, data rows only (2-5) — NOT the header.\n",[47,751,752,755,757,759,761,763,765,767,769,771,773,775,777,779,781],{"class":49,"line":487},[47,753,754],{"class":98},"cats ",[47,756,121],{"class":94},[47,758,453],{"class":98},[47,760,457],{"class":456},[47,762,121],{"class":94},[47,764,472],{"class":195},[47,766,163],{"class":98},[47,768,467],{"class":456},[47,770,121],{"class":94},[47,772,462],{"class":195},[47,774,163],{"class":98},[47,776,477],{"class":456},[47,778,121],{"class":94},[47,780,482],{"class":195},[47,782,256],{"class":98},[47,784,785],{"class":49,"line":503},[47,786,787],{"class":98},"chart.set_categories(cats)\n",[47,789,790],{"class":49,"line":508},[47,791,112],{"emptyLinePlaceholder":111},[47,793,794,796,799],{"class":49,"line":538},[47,795,250],{"class":98},[47,797,798],{"class":57},"\"bar_step3.xlsx\"",[47,800,256],{"class":98},[47,802,804,806,808,811],{"class":49,"line":803},20,[47,805,262],{"class":195},[47,807,265],{"class":98},[47,809,810],{"class":57},"\"Categories bound to A2:A5 (Widget, Gadget, Gizmo, Doohickey)\"",[47,812,256],{"class":98},[10,814,815,816,819,820,822,823,819,826,828],{},"The asymmetry is the part people trip on: the ",[571,817,818],{},"value"," ",[14,821,24],{}," starts at row 1 (header included), the ",[571,824,825],{},"category",[14,827,24],{}," starts at row 2 (header excluded).",[33,830,832],{"id":831},"step-4-title-axes-style-and-anchor","Step 4 — Title, axes, style, and anchor",[10,834,835,836,839],{},"Finish with labels and a style preset, then drop the chart onto the sheet. ",[14,837,838],{},"ws.add_chart(chart, \"D2\")"," puts the chart's top-left corner at D2.",[38,841,843],{"className":78,"code":842,"language":80,"meta":43,"style":43},"# pip install openpyxl\nfrom openpyxl import Workbook\nfrom openpyxl.chart import BarChart, Reference\n\nwb = Workbook()\nws = wb.active\nws.append([\"Product\", \"Units Sold\"])\nfor row in [(\"Widget\", 340), (\"Gadget\", 280), (\"Gizmo\", 410), (\"Doohickey\", 195)]:\n    ws.append(row)\n\nchart = BarChart()\nchart.type = \"col\"\nchart.title = \"Units Sold by Product\"\nchart.x_axis.title = \"Product\"\nchart.y_axis.title = \"Units\"\nchart.style = 12        # built-in color preset, 1-48\nchart.legend = None     # single series, so no legend needed\n\nchart.add_data(Reference(ws, min_col=2, min_row=1, max_row=5), titles_from_data=True)\nchart.set_categories(Reference(ws, min_col=1, min_row=2, max_row=5))\n\nws.add_chart(chart, \"D2\")\nwb.save(\"bar_chart_final.xlsx\")\nprint(\"Saved bar_chart_final.xlsx — open and click the chart to edit it\")\n",[14,844,845,849,859,869,873,881,889,901,943,947,951,959,967,977,987,997,1010,1023,1027,1063,1093,1098,1109,1119],{"__ignoreMap":43},[47,846,847],{"class":49,"line":50},[47,848,88],{"class":87},[47,850,851,853,855,857],{"class":49,"line":91},[47,852,95],{"class":94},[47,854,99],{"class":98},[47,856,102],{"class":94},[47,858,105],{"class":98},[47,860,861,863,865,867],{"class":49,"line":108},[47,862,95],{"class":94},[47,864,320],{"class":98},[47,866,102],{"class":94},[47,868,325],{"class":98},[47,870,871],{"class":49,"line":115},[47,872,112],{"emptyLinePlaceholder":111},[47,874,875,877,879],{"class":49,"line":127},[47,876,118],{"class":98},[47,878,121],{"class":94},[47,880,124],{"class":98},[47,882,883,885,887],{"class":49,"line":138},[47,884,130],{"class":98},[47,886,121],{"class":94},[47,888,135],{"class":98},[47,890,891,893,895,897,899],{"class":49,"line":149},[47,892,157],{"class":98},[47,894,160],{"class":57},[47,896,163],{"class":98},[47,898,166],{"class":57},[47,900,358],{"class":98},[47,902,903,905,907,909,911,913,915,917,919,921,923,925,927,929,931,933,935,937,939,941],{"class":49,"line":154},[47,904,178],{"class":94},[47,906,181],{"class":98},[47,908,184],{"class":94},[47,910,187],{"class":98},[47,912,190],{"class":57},[47,914,163],{"class":98},[47,916,196],{"class":195},[47,918,199],{"class":98},[47,920,202],{"class":57},[47,922,163],{"class":98},[47,924,207],{"class":195},[47,926,199],{"class":98},[47,928,212],{"class":57},[47,930,163],{"class":98},[47,932,217],{"class":195},[47,934,199],{"class":98},[47,936,222],{"class":57},[47,938,163],{"class":98},[47,940,227],{"class":195},[47,942,230],{"class":98},[47,944,945],{"class":49,"line":175},[47,946,405],{"class":98},[47,948,949],{"class":49,"line":233},[47,950,112],{"emptyLinePlaceholder":111},[47,952,953,955,957],{"class":49,"line":242},[47,954,414],{"class":98},[47,956,121],{"class":94},[47,958,419],{"class":98},[47,960,961,963,965],{"class":49,"line":247},[47,962,424],{"class":98},[47,964,121],{"class":94},[47,966,702],{"class":57},[47,968,969,972,974],{"class":49,"line":259},[47,970,971],{"class":98},"chart.title ",[47,973,121],{"class":94},[47,975,976],{"class":57}," \"Units Sold by Product\"\n",[47,978,979,982,984],{"class":49,"line":439},[47,980,981],{"class":98},"chart.x_axis.title ",[47,983,121],{"class":94},[47,985,986],{"class":57}," \"Product\"\n",[47,988,989,992,994],{"class":49,"line":445},[47,990,991],{"class":98},"chart.y_axis.title ",[47,993,121],{"class":94},[47,995,996],{"class":57}," \"Units\"\n",[47,998,999,1002,1004,1007],{"class":49,"line":487},[47,1000,1001],{"class":98},"chart.style ",[47,1003,121],{"class":94},[47,1005,1006],{"class":195}," 12",[47,1008,1009],{"class":87},"        # built-in color preset, 1-48\n",[47,1011,1012,1015,1017,1020],{"class":49,"line":503},[47,1013,1014],{"class":98},"chart.legend ",[47,1016,121],{"class":94},[47,1018,1019],{"class":195}," None",[47,1021,1022],{"class":87},"     # single series, so no legend needed\n",[47,1024,1025],{"class":49,"line":508},[47,1026,112],{"emptyLinePlaceholder":111},[47,1028,1029,1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061],{"class":49,"line":538},[47,1030,707],{"class":98},[47,1032,457],{"class":456},[47,1034,121],{"class":94},[47,1036,462],{"class":195},[47,1038,163],{"class":98},[47,1040,467],{"class":456},[47,1042,121],{"class":94},[47,1044,472],{"class":195},[47,1046,163],{"class":98},[47,1048,477],{"class":456},[47,1050,121],{"class":94},[47,1052,482],{"class":195},[47,1054,732],{"class":98},[47,1056,493],{"class":456},[47,1058,121],{"class":94},[47,1060,498],{"class":195},[47,1062,256],{"class":98},[47,1064,1065,1068,1070,1072,1074,1076,1078,1080,1082,1084,1086,1088,1090],{"class":49,"line":803},[47,1066,1067],{"class":98},"chart.set_categories(Reference(ws, ",[47,1069,457],{"class":456},[47,1071,121],{"class":94},[47,1073,472],{"class":195},[47,1075,163],{"class":98},[47,1077,467],{"class":456},[47,1079,121],{"class":94},[47,1081,462],{"class":195},[47,1083,163],{"class":98},[47,1085,477],{"class":456},[47,1087,121],{"class":94},[47,1089,482],{"class":195},[47,1091,1092],{"class":98},"))\n",[47,1094,1096],{"class":49,"line":1095},21,[47,1097,112],{"emptyLinePlaceholder":111},[47,1099,1101,1104,1107],{"class":49,"line":1100},22,[47,1102,1103],{"class":98},"ws.add_chart(chart, ",[47,1105,1106],{"class":57},"\"D2\"",[47,1108,256],{"class":98},[47,1110,1112,1114,1117],{"class":49,"line":1111},23,[47,1113,250],{"class":98},[47,1115,1116],{"class":57},"\"bar_chart_final.xlsx\"",[47,1118,256],{"class":98},[47,1120,1122,1124,1126,1129],{"class":49,"line":1121},24,[47,1123,262],{"class":195},[47,1125,265],{"class":98},[47,1127,1128],{"class":57},"\"Saved bar_chart_final.xlsx — open and click the chart to edit it\"",[47,1130,256],{"class":98},[10,1132,1133,1134,1137],{},"Open ",[14,1135,1136],{},"bar_chart_final.xlsx"," in Excel or LibreOffice: it is a real chart, so you can drag it, change its colors, or extend its data range from the UI.",[33,1139,1141],{"id":1140},"common-pitfalls","Common pitfalls",[1143,1144,1145,1161],"table",{},[1146,1147,1148],"thead",{},[1149,1150,1151,1155,1158],"tr",{},[1152,1153,1154],"th",{},"Symptom",[1152,1156,1157],{},"Cause",[1152,1159,1160],{},"Fix",[1162,1163,1164,1189,1211,1229,1246,1257],"tbody",{},[1149,1165,1166,1170,1175],{},[1167,1168,1169],"td",{},"Chart is missing the last bar",[1167,1171,1172,1174],{},[14,1173,477],{}," is one too low (off by one)",[1167,1176,1177,1178,1180,1181,1184,1185,1188],{},"With a header in row 1 and N data rows, ",[14,1179,477],{}," is ",[14,1182,1183],{},"N + 1",". Four products → ",[14,1186,1187],{},"max_row=5",".",[1149,1190,1191,1194,1200],{},[1167,1192,1193],{},"Series is named \"Series 1\"",[1167,1195,1196,1197,1199],{},"Header not included or ",[14,1198,493],{}," omitted",[1167,1201,1202,1203,1205,1206,1208,1209,1188],{},"Start the value ",[14,1204,24],{}," at ",[14,1207,289],{}," and pass ",[14,1210,293],{},[1149,1212,1213,1216,1222],{},[1167,1214,1215],{},"An extra bar appears at the front",[1167,1217,1218,1219,1221],{},"Header row included in the ",[571,1220,825],{}," range",[1167,1223,1224,1225,1228],{},"Categories must start at ",[14,1226,1227],{},"min_row=2","; the header is not a category.",[1149,1230,1231,1234,1240],{},[1167,1232,1233],{},"X-axis shows 1, 2, 3, 4",[1167,1235,1236,1239],{},[14,1237,1238],{},"set_categories"," was never called",[1167,1241,1242,1243,1188],{},"Bind the label column with ",[14,1244,1245],{},"set_categories(Reference(...))",[1149,1247,1248,1251,1254],{},[1167,1249,1250],{},"Bars and labels are swapped\u002Fempty",[1167,1252,1253],{},"Value and category ranges point at the wrong columns",[1167,1255,1256],{},"Value range = numeric column; category range = label column. Don't cross them.",[1149,1258,1259,1262,1271],{},[1167,1260,1261],{},"Bars run horizontally, not vertically",[1167,1263,1264,1267,1268],{},[14,1265,1266],{},"chart.type"," left at default ",[14,1269,1270],{},"\"bar\"",[1167,1272,1273,1274,1277],{},"Set ",[14,1275,1276],{},"chart.type = \"col\""," for vertical columns.",[33,1279,1281],{"id":1280},"performance-and-scale","Performance and scale",[10,1283,1284,1285,1288],{},"A bar chart is bound to a cell range, so its cost is independent of how many points it shows — Excel renders it, openpyxl only writes the definition. Writing the underlying data is the only thing that scales with size, and even tens of thousands of rows write in well under a second. Bar charts become unreadable long before they become slow: past roughly 20–30 categories, switch to a different visualization rather than a wall of bars. If you are writing many large sheets, open the workbook with ",[14,1286,1287],{},"write_only=True"," for the data and add the chart on a normal worksheet.",[33,1290,1292],{"id":1291},"frequently-asked-questions","Frequently asked questions",[10,1294,1295,1298,1299,1302,1303,1306,1307,1309],{},[571,1296,1297],{},"How do I make horizontal bars instead of columns?"," Set ",[14,1300,1301],{},"chart.type = \"bar\"",". The default in this guide is ",[14,1304,1305],{},"\"col\""," (vertical); ",[14,1308,1270],{}," rotates them to horizontal.",[10,1311,1312,1315,1316,1318,1319,1322,1323,1326,1327,1330,1331,1334],{},[571,1313,1314],{},"Can I stack or group multiple series?"," Yes. Add more value columns to the ",[14,1317,24],{}," (widen ",[14,1320,1321],{},"max_col","), and set ",[14,1324,1325],{},"chart.grouping = \"stacked\""," or ",[14,1328,1329],{},"\"clustered\"",". Add ",[14,1332,1333],{},"chart.overlap = 100"," for true stacking.",[10,1336,1337,1340,1341,1343,1344,1346,1347,1349],{},[571,1338,1339],{},"Why does my chart look fine but show no data when opened?"," The ",[14,1342,24],{}," rows don't match where the data actually sits. Re-check that ",[14,1345,467],{},"\u002F",[14,1348,477],{}," cover exactly your header-plus-data block.",[10,1351,1352,1355,1356,1359,1360,1363,1364,1188],{},[571,1353,1354],{},"Can I show the value on each bar?"," Yes — ",[14,1357,1358],{},"from openpyxl.chart.label import DataLabelList",", then ",[14,1361,1362],{},"chart.dataLabels = DataLabelList()"," and ",[14,1365,1366],{},"chart.dataLabels.showVal = True",[33,1368,1370],{"id":1369},"conclusion","Conclusion",[10,1372,1373,1374,1363,1376,1378,1379,1381,1382,1384],{},"A bar chart in openpyxl is four steps: write a header-plus-values table, bind the value column with ",[14,1375,24],{},[14,1377,293],{},", bind the label column with ",[14,1380,1238],{}," (header excluded), then label and anchor it. The one rule that prevents most bugs is the row asymmetry — values include the header row, categories don't — and getting ",[14,1383,477],{}," right (data rows plus one for the header).",[33,1386,1388],{"id":1387},"where-to-go-next","Where to go next",[1390,1391,1392,1398,1405],"ul",{},[1393,1394,1395,1396],"li",{},"Up to the cluster: ",[27,1397,30],{"href":29},[1393,1399,1400,1401],{},"The sibling guide: ",[27,1402,1404],{"href":1403},"\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",[1393,1406,1407,1408],{},"Related: ",[27,1409,1411],{"href":1410},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002F","Building Multi-Sheet Excel Dashboards",[1413,1414,1415],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":43,"searchDepth":91,"depth":91,"links":1417},[1418,1419,1420,1421,1422,1423,1424,1425,1426,1427],{"id":35,"depth":91,"text":36},{"id":71,"depth":91,"text":72},{"id":279,"depth":91,"text":280},{"id":561,"depth":91,"text":562},{"id":831,"depth":91,"text":832},{"id":1140,"depth":91,"text":1141},{"id":1280,"depth":91,"text":1281},{"id":1291,"depth":91,"text":1292},{"id":1369,"depth":91,"text":1370},{"id":1387,"depth":91,"text":1388},"Build a native, editable Excel bar chart from Python with openpyxl: write sample data, bind it with Reference, set categories and titles, pick a style, and anchor it.","md",{},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl",{"title":5,"description":1433},"Step-by-step openpyxl bar chart: write category and value data, bind it with Reference and titles_from_data, set categories, title and style, then anchor it to a cell.","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl\u002Findex","-ujaf6WnIyJuTH9_HsjfQh_Li6HTRsDzgpvHqmAVqqo",[1437,1440],{"title":1404,"path":1438,"stem":1439,"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":1441,"path":1442,"stem":1443,"children":-1},"Inserting Images and Logos into Excel","\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel","formatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Findex",1781773161037]