[{"data":1,"prerenderedAt":2062},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python":2055},{"id":4,"title":5,"body":6,"description":2046,"extension":2047,"meta":2048,"navigation":124,"path":2049,"seo":2050,"stem":2053,"__hash__":2054},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python\u002Findex.md","Add a Line Chart to an Excel Report with Python",{"type":7,"value":8,"toc":2034},"minimark",[9,24,29,55,65,69,76,448,451,455,462,850,859,863,873,1242,1264,1268,1278,1769,1778,1782,1913,1917,1920,1924,1933,1954,1971,1985,1989,2004,2008,2030],[10,11,12,13,18,19,23],"p",{},"This page adds a line chart to an Excel report from Python with openpyxl, the right choice when a metric moves over time. You will write a dated time-series, plot a single line, add a second series, switch the x-axis to read real dates, and turn on markers — all producing a native, editable Excel chart. It is the time-series companion to the parent cluster, ",[14,15,17],"a",{"href":16},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002F","Creating Charts in Excel with openpyxl",", and to its ",[14,20,22],{"href":21},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-bar-chart-in-excel-with-openpyxl\u002F","bar chart guide",".",[25,26,28],"h2",{"id":27},"prerequisites","Prerequisites",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-bash shiki shiki-themes github-light github-dark","pip install openpyxl\n","bash","",[37,38,39],"code",{"__ignoreMap":35},[40,41,44,48,52],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sScJk","pip",[40,49,51],{"class":50},"sZZnC"," install",[40,53,54],{"class":50}," openpyxl\n",[10,56,57,60,61,64],{},[37,58,59],{},"datetime"," is used to write real date values into the sheet and comes with the standard library. Any current openpyxl release has the ",[37,62,63],{},"openpyxl.chart"," API below.",[25,66,68],{"id":67},"step-1-write-time-series-data","Step 1 — Write time-series data",[10,70,71,72,75],{},"Write a date column and one or more metric columns, with a header row so each series can take its name from it. Use real ",[37,73,74],{},"datetime.date"," objects, not strings — that is what lets the x-axis behave as dates later.",[30,77,81],{"className":78,"code":79,"language":80,"meta":35,"style":35},"language-python shiki shiki-themes github-light github-dark","# pip install openpyxl\nfrom datetime import date\nfrom openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.title = \"Traffic\"\n\nws.append([\"Date\", \"Visitors\", \"Signups\"])     # row 1: header\nrows = [\n    (date(2026, 1, 1), 1200, 90),\n    (date(2026, 1, 8), 1340, 110),\n    (date(2026, 1, 15), 1290, 105),\n    (date(2026, 1, 22), 1510, 130),\n    (date(2026, 1, 29), 1625, 142),\n]\nfor r in rows:\n    ws.append(r)\n\nfor cell in ws[\"A\"][1:]:        # format the date column so Excel shows dates\n    cell.number_format = \"yyyy-mm-dd\"\n\nwb.save(\"line_step1.xlsx\")\nprint(\"Wrote 5 weekly rows: Date, Visitors, Signups\")\n","python",[37,82,83,89,106,119,126,138,149,160,165,191,202,235,263,291,319,347,353,368,374,379,406,417,422,434],{"__ignoreMap":35},[40,84,85],{"class":42,"line":43},[40,86,88],{"class":87},"sJ8bj","# pip install openpyxl\n",[40,90,92,96,100,103],{"class":42,"line":91},2,[40,93,95],{"class":94},"szBVR","from",[40,97,99],{"class":98},"sVt8B"," datetime ",[40,101,102],{"class":94},"import",[40,104,105],{"class":98}," date\n",[40,107,109,111,114,116],{"class":42,"line":108},3,[40,110,95],{"class":94},[40,112,113],{"class":98}," openpyxl ",[40,115,102],{"class":94},[40,117,118],{"class":98}," Workbook\n",[40,120,122],{"class":42,"line":121},4,[40,123,125],{"emptyLinePlaceholder":124},true,"\n",[40,127,129,132,135],{"class":42,"line":128},5,[40,130,131],{"class":98},"wb ",[40,133,134],{"class":94},"=",[40,136,137],{"class":98}," Workbook()\n",[40,139,141,144,146],{"class":42,"line":140},6,[40,142,143],{"class":98},"ws ",[40,145,134],{"class":94},[40,147,148],{"class":98}," wb.active\n",[40,150,152,155,157],{"class":42,"line":151},7,[40,153,154],{"class":98},"ws.title ",[40,156,134],{"class":94},[40,158,159],{"class":50}," \"Traffic\"\n",[40,161,163],{"class":42,"line":162},8,[40,164,125],{"emptyLinePlaceholder":124},[40,166,168,171,174,177,180,182,185,188],{"class":42,"line":167},9,[40,169,170],{"class":98},"ws.append([",[40,172,173],{"class":50},"\"Date\"",[40,175,176],{"class":98},", ",[40,178,179],{"class":50},"\"Visitors\"",[40,181,176],{"class":98},[40,183,184],{"class":50},"\"Signups\"",[40,186,187],{"class":98},"])     ",[40,189,190],{"class":87},"# row 1: header\n",[40,192,194,197,199],{"class":42,"line":193},10,[40,195,196],{"class":98},"rows ",[40,198,134],{"class":94},[40,200,201],{"class":98}," [\n",[40,203,205,208,212,214,217,219,221,224,227,229,232],{"class":42,"line":204},11,[40,206,207],{"class":98},"    (date(",[40,209,211],{"class":210},"sj4cs","2026",[40,213,176],{"class":98},[40,215,216],{"class":210},"1",[40,218,176],{"class":98},[40,220,216],{"class":210},[40,222,223],{"class":98},"), ",[40,225,226],{"class":210},"1200",[40,228,176],{"class":98},[40,230,231],{"class":210},"90",[40,233,234],{"class":98},"),\n",[40,236,238,240,242,244,246,248,251,253,256,258,261],{"class":42,"line":237},12,[40,239,207],{"class":98},[40,241,211],{"class":210},[40,243,176],{"class":98},[40,245,216],{"class":210},[40,247,176],{"class":98},[40,249,250],{"class":210},"8",[40,252,223],{"class":98},[40,254,255],{"class":210},"1340",[40,257,176],{"class":98},[40,259,260],{"class":210},"110",[40,262,234],{"class":98},[40,264,266,268,270,272,274,276,279,281,284,286,289],{"class":42,"line":265},13,[40,267,207],{"class":98},[40,269,211],{"class":210},[40,271,176],{"class":98},[40,273,216],{"class":210},[40,275,176],{"class":98},[40,277,278],{"class":210},"15",[40,280,223],{"class":98},[40,282,283],{"class":210},"1290",[40,285,176],{"class":98},[40,287,288],{"class":210},"105",[40,290,234],{"class":98},[40,292,294,296,298,300,302,304,307,309,312,314,317],{"class":42,"line":293},14,[40,295,207],{"class":98},[40,297,211],{"class":210},[40,299,176],{"class":98},[40,301,216],{"class":210},[40,303,176],{"class":98},[40,305,306],{"class":210},"22",[40,308,223],{"class":98},[40,310,311],{"class":210},"1510",[40,313,176],{"class":98},[40,315,316],{"class":210},"130",[40,318,234],{"class":98},[40,320,322,324,326,328,330,332,335,337,340,342,345],{"class":42,"line":321},15,[40,323,207],{"class":98},[40,325,211],{"class":210},[40,327,176],{"class":98},[40,329,216],{"class":210},[40,331,176],{"class":98},[40,333,334],{"class":210},"29",[40,336,223],{"class":98},[40,338,339],{"class":210},"1625",[40,341,176],{"class":98},[40,343,344],{"class":210},"142",[40,346,234],{"class":98},[40,348,350],{"class":42,"line":349},16,[40,351,352],{"class":98},"]\n",[40,354,356,359,362,365],{"class":42,"line":355},17,[40,357,358],{"class":94},"for",[40,360,361],{"class":98}," r ",[40,363,364],{"class":94},"in",[40,366,367],{"class":98}," rows:\n",[40,369,371],{"class":42,"line":370},18,[40,372,373],{"class":98},"    ws.append(r)\n",[40,375,377],{"class":42,"line":376},19,[40,378,125],{"emptyLinePlaceholder":124},[40,380,382,384,387,389,392,395,398,400,403],{"class":42,"line":381},20,[40,383,358],{"class":94},[40,385,386],{"class":98}," cell ",[40,388,364],{"class":94},[40,390,391],{"class":98}," ws[",[40,393,394],{"class":50},"\"A\"",[40,396,397],{"class":98},"][",[40,399,216],{"class":210},[40,401,402],{"class":98},":]:        ",[40,404,405],{"class":87},"# format the date column so Excel shows dates\n",[40,407,409,412,414],{"class":42,"line":408},21,[40,410,411],{"class":98},"    cell.number_format ",[40,413,134],{"class":94},[40,415,416],{"class":50}," \"yyyy-mm-dd\"\n",[40,418,420],{"class":42,"line":419},22,[40,421,125],{"emptyLinePlaceholder":124},[40,423,425,428,431],{"class":42,"line":424},23,[40,426,427],{"class":98},"wb.save(",[40,429,430],{"class":50},"\"line_step1.xlsx\"",[40,432,433],{"class":98},")\n",[40,435,437,440,443,446],{"class":42,"line":436},24,[40,438,439],{"class":210},"print",[40,441,442],{"class":98},"(",[40,444,445],{"class":50},"\"Wrote 5 weekly rows: Date, Visitors, Signups\"",[40,447,433],{"class":98},[10,449,450],{},"The data sits in A1:C6 — header in row 1, five data rows below.",[25,452,454],{"id":453},"step-2-plot-a-single-line","Step 2 — Plot a single line",[10,456,457,458,461],{},"Bind one metric column with ",[37,459,460],{},"Reference",", include the header for the series name, and set the date column as categories.",[30,463,465],{"className":78,"code":464,"language":80,"meta":35,"style":35},"# pip install openpyxl\nfrom datetime import date\nfrom openpyxl import Workbook\nfrom openpyxl.chart import LineChart, Reference\n\nwb = Workbook()\nws = wb.active\nws.append([\"Date\", \"Visitors\", \"Signups\"])\nfor r in [(date(2026, 1, 1), 1200, 90), (date(2026, 1, 8), 1340, 110),\n          (date(2026, 1, 15), 1290, 105), (date(2026, 1, 22), 1510, 130),\n          (date(2026, 1, 29), 1625, 142)]:\n    ws.append(r)\n\nchart = LineChart()\nchart.title = \"Weekly Visitors\"\nchart.y_axis.title = \"Visitors\"\nchart.x_axis.title = \"Week\"\n\ndata = Reference(ws, min_col=2, min_row=1, max_row=6)   # Visitors + header\nchart.add_data(data, titles_from_data=True)\ncats = Reference(ws, min_col=1, min_row=2, max_row=6)   # dates, no header\nchart.set_categories(cats)\n\nws.add_chart(chart, \"E2\")\nwb.save(\"line_single.xlsx\")\nprint(\"Saved line_single.xlsx\")\n",[37,466,467,471,481,491,503,507,515,523,540,592,637,662,666,670,680,690,700,710,714,758,773,809,814,818,828,838],{"__ignoreMap":35},[40,468,469],{"class":42,"line":43},[40,470,88],{"class":87},[40,472,473,475,477,479],{"class":42,"line":91},[40,474,95],{"class":94},[40,476,99],{"class":98},[40,478,102],{"class":94},[40,480,105],{"class":98},[40,482,483,485,487,489],{"class":42,"line":108},[40,484,95],{"class":94},[40,486,113],{"class":98},[40,488,102],{"class":94},[40,490,118],{"class":98},[40,492,493,495,498,500],{"class":42,"line":121},[40,494,95],{"class":94},[40,496,497],{"class":98}," openpyxl.chart ",[40,499,102],{"class":94},[40,501,502],{"class":98}," LineChart, Reference\n",[40,504,505],{"class":42,"line":128},[40,506,125],{"emptyLinePlaceholder":124},[40,508,509,511,513],{"class":42,"line":140},[40,510,131],{"class":98},[40,512,134],{"class":94},[40,514,137],{"class":98},[40,516,517,519,521],{"class":42,"line":151},[40,518,143],{"class":98},[40,520,134],{"class":94},[40,522,148],{"class":98},[40,524,525,527,529,531,533,535,537],{"class":42,"line":162},[40,526,170],{"class":98},[40,528,173],{"class":50},[40,530,176],{"class":98},[40,532,179],{"class":50},[40,534,176],{"class":98},[40,536,184],{"class":50},[40,538,539],{"class":98},"])\n",[40,541,542,544,546,548,551,553,555,557,559,561,563,565,567,569,572,574,576,578,580,582,584,586,588,590],{"class":42,"line":167},[40,543,358],{"class":94},[40,545,361],{"class":98},[40,547,364],{"class":94},[40,549,550],{"class":98}," [(date(",[40,552,211],{"class":210},[40,554,176],{"class":98},[40,556,216],{"class":210},[40,558,176],{"class":98},[40,560,216],{"class":210},[40,562,223],{"class":98},[40,564,226],{"class":210},[40,566,176],{"class":98},[40,568,231],{"class":210},[40,570,571],{"class":98},"), (date(",[40,573,211],{"class":210},[40,575,176],{"class":98},[40,577,216],{"class":210},[40,579,176],{"class":98},[40,581,250],{"class":210},[40,583,223],{"class":98},[40,585,255],{"class":210},[40,587,176],{"class":98},[40,589,260],{"class":210},[40,591,234],{"class":98},[40,593,594,597,599,601,603,605,607,609,611,613,615,617,619,621,623,625,627,629,631,633,635],{"class":42,"line":193},[40,595,596],{"class":98},"          (date(",[40,598,211],{"class":210},[40,600,176],{"class":98},[40,602,216],{"class":210},[40,604,176],{"class":98},[40,606,278],{"class":210},[40,608,223],{"class":98},[40,610,283],{"class":210},[40,612,176],{"class":98},[40,614,288],{"class":210},[40,616,571],{"class":98},[40,618,211],{"class":210},[40,620,176],{"class":98},[40,622,216],{"class":210},[40,624,176],{"class":98},[40,626,306],{"class":210},[40,628,223],{"class":98},[40,630,311],{"class":210},[40,632,176],{"class":98},[40,634,316],{"class":210},[40,636,234],{"class":98},[40,638,639,641,643,645,647,649,651,653,655,657,659],{"class":42,"line":204},[40,640,596],{"class":98},[40,642,211],{"class":210},[40,644,176],{"class":98},[40,646,216],{"class":210},[40,648,176],{"class":98},[40,650,334],{"class":210},[40,652,223],{"class":98},[40,654,339],{"class":210},[40,656,176],{"class":98},[40,658,344],{"class":210},[40,660,661],{"class":98},")]:\n",[40,663,664],{"class":42,"line":237},[40,665,373],{"class":98},[40,667,668],{"class":42,"line":265},[40,669,125],{"emptyLinePlaceholder":124},[40,671,672,675,677],{"class":42,"line":293},[40,673,674],{"class":98},"chart ",[40,676,134],{"class":94},[40,678,679],{"class":98}," LineChart()\n",[40,681,682,685,687],{"class":42,"line":321},[40,683,684],{"class":98},"chart.title ",[40,686,134],{"class":94},[40,688,689],{"class":50}," \"Weekly Visitors\"\n",[40,691,692,695,697],{"class":42,"line":349},[40,693,694],{"class":98},"chart.y_axis.title ",[40,696,134],{"class":94},[40,698,699],{"class":50}," \"Visitors\"\n",[40,701,702,705,707],{"class":42,"line":355},[40,703,704],{"class":98},"chart.x_axis.title ",[40,706,134],{"class":94},[40,708,709],{"class":50}," \"Week\"\n",[40,711,712],{"class":42,"line":370},[40,713,125],{"emptyLinePlaceholder":124},[40,715,716,719,721,724,728,730,733,735,738,740,742,744,747,749,752,755],{"class":42,"line":376},[40,717,718],{"class":98},"data ",[40,720,134],{"class":94},[40,722,723],{"class":98}," Reference(ws, ",[40,725,727],{"class":726},"s4XuR","min_col",[40,729,134],{"class":94},[40,731,732],{"class":210},"2",[40,734,176],{"class":98},[40,736,737],{"class":726},"min_row",[40,739,134],{"class":94},[40,741,216],{"class":210},[40,743,176],{"class":98},[40,745,746],{"class":726},"max_row",[40,748,134],{"class":94},[40,750,751],{"class":210},"6",[40,753,754],{"class":98},")   ",[40,756,757],{"class":87},"# Visitors + header\n",[40,759,760,763,766,768,771],{"class":42,"line":381},[40,761,762],{"class":98},"chart.add_data(data, ",[40,764,765],{"class":726},"titles_from_data",[40,767,134],{"class":94},[40,769,770],{"class":210},"True",[40,772,433],{"class":98},[40,774,775,778,780,782,784,786,788,790,792,794,796,798,800,802,804,806],{"class":42,"line":408},[40,776,777],{"class":98},"cats ",[40,779,134],{"class":94},[40,781,723],{"class":98},[40,783,727],{"class":726},[40,785,134],{"class":94},[40,787,216],{"class":210},[40,789,176],{"class":98},[40,791,737],{"class":726},[40,793,134],{"class":94},[40,795,732],{"class":210},[40,797,176],{"class":98},[40,799,746],{"class":726},[40,801,134],{"class":94},[40,803,751],{"class":210},[40,805,754],{"class":98},[40,807,808],{"class":87},"# dates, no header\n",[40,810,811],{"class":42,"line":419},[40,812,813],{"class":98},"chart.set_categories(cats)\n",[40,815,816],{"class":42,"line":424},[40,817,125],{"emptyLinePlaceholder":124},[40,819,820,823,826],{"class":42,"line":436},[40,821,822],{"class":98},"ws.add_chart(chart, ",[40,824,825],{"class":50},"\"E2\"",[40,827,433],{"class":98},[40,829,831,833,836],{"class":42,"line":830},25,[40,832,427],{"class":98},[40,834,835],{"class":50},"\"line_single.xlsx\"",[40,837,433],{"class":98},[40,839,841,843,845,848],{"class":42,"line":840},26,[40,842,439],{"class":210},[40,844,442],{"class":98},[40,846,847],{"class":50},"\"Saved line_single.xlsx\"",[40,849,433],{"class":98},[10,851,852,853,855,856,858],{},"As with bar charts, the value ",[37,854,460],{}," includes row 1 (for the name) and the category ",[37,857,460],{}," starts at row 2.",[25,860,862],{"id":861},"step-3-plot-multiple-series","Step 3 — Plot multiple series",[10,864,865,866,868,869,872],{},"To plot Visitors and Signups together, widen the value ",[37,867,460],{}," to cover both columns. ",[37,870,871],{},"add_data"," creates one series per column, and the header row names them.",[30,874,876],{"className":78,"code":875,"language":80,"meta":35,"style":35},"# pip install openpyxl\nfrom datetime import date\nfrom openpyxl import Workbook\nfrom openpyxl.chart import LineChart, Reference\n\nwb = Workbook()\nws = wb.active\nws.append([\"Date\", \"Visitors\", \"Signups\"])\nfor r in [(date(2026, 1, 1), 1200, 90), (date(2026, 1, 8), 1340, 110),\n          (date(2026, 1, 15), 1290, 105), (date(2026, 1, 22), 1510, 130),\n          (date(2026, 1, 29), 1625, 142)]:\n    ws.append(r)\n\nchart = LineChart()\nchart.title = \"Visitors vs Signups\"\nchart.y_axis.title = \"Count\"\nchart.x_axis.title = \"Week\"\n\n# Two metric columns (B and C) -> two series.\ndata = Reference(ws, min_col=2, max_col=3, min_row=1, max_row=6)\nchart.add_data(data, titles_from_data=True)\nchart.set_categories(Reference(ws, min_col=1, min_row=2, max_row=6))\n\nprint(\"series:\", len(chart.series))   # -> 2, legend appears automatically\nws.add_chart(chart, \"E2\")\nwb.save(\"line_multi.xlsx\")\n",[37,877,878,882,892,902,912,916,924,932,948,998,1042,1066,1070,1074,1082,1091,1100,1108,1112,1117,1159,1171,1201,1205,1225,1233],{"__ignoreMap":35},[40,879,880],{"class":42,"line":43},[40,881,88],{"class":87},[40,883,884,886,888,890],{"class":42,"line":91},[40,885,95],{"class":94},[40,887,99],{"class":98},[40,889,102],{"class":94},[40,891,105],{"class":98},[40,893,894,896,898,900],{"class":42,"line":108},[40,895,95],{"class":94},[40,897,113],{"class":98},[40,899,102],{"class":94},[40,901,118],{"class":98},[40,903,904,906,908,910],{"class":42,"line":121},[40,905,95],{"class":94},[40,907,497],{"class":98},[40,909,102],{"class":94},[40,911,502],{"class":98},[40,913,914],{"class":42,"line":128},[40,915,125],{"emptyLinePlaceholder":124},[40,917,918,920,922],{"class":42,"line":140},[40,919,131],{"class":98},[40,921,134],{"class":94},[40,923,137],{"class":98},[40,925,926,928,930],{"class":42,"line":151},[40,927,143],{"class":98},[40,929,134],{"class":94},[40,931,148],{"class":98},[40,933,934,936,938,940,942,944,946],{"class":42,"line":162},[40,935,170],{"class":98},[40,937,173],{"class":50},[40,939,176],{"class":98},[40,941,179],{"class":50},[40,943,176],{"class":98},[40,945,184],{"class":50},[40,947,539],{"class":98},[40,949,950,952,954,956,958,960,962,964,966,968,970,972,974,976,978,980,982,984,986,988,990,992,994,996],{"class":42,"line":167},[40,951,358],{"class":94},[40,953,361],{"class":98},[40,955,364],{"class":94},[40,957,550],{"class":98},[40,959,211],{"class":210},[40,961,176],{"class":98},[40,963,216],{"class":210},[40,965,176],{"class":98},[40,967,216],{"class":210},[40,969,223],{"class":98},[40,971,226],{"class":210},[40,973,176],{"class":98},[40,975,231],{"class":210},[40,977,571],{"class":98},[40,979,211],{"class":210},[40,981,176],{"class":98},[40,983,216],{"class":210},[40,985,176],{"class":98},[40,987,250],{"class":210},[40,989,223],{"class":98},[40,991,255],{"class":210},[40,993,176],{"class":98},[40,995,260],{"class":210},[40,997,234],{"class":98},[40,999,1000,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028,1030,1032,1034,1036,1038,1040],{"class":42,"line":193},[40,1001,596],{"class":98},[40,1003,211],{"class":210},[40,1005,176],{"class":98},[40,1007,216],{"class":210},[40,1009,176],{"class":98},[40,1011,278],{"class":210},[40,1013,223],{"class":98},[40,1015,283],{"class":210},[40,1017,176],{"class":98},[40,1019,288],{"class":210},[40,1021,571],{"class":98},[40,1023,211],{"class":210},[40,1025,176],{"class":98},[40,1027,216],{"class":210},[40,1029,176],{"class":98},[40,1031,306],{"class":210},[40,1033,223],{"class":98},[40,1035,311],{"class":210},[40,1037,176],{"class":98},[40,1039,316],{"class":210},[40,1041,234],{"class":98},[40,1043,1044,1046,1048,1050,1052,1054,1056,1058,1060,1062,1064],{"class":42,"line":204},[40,1045,596],{"class":98},[40,1047,211],{"class":210},[40,1049,176],{"class":98},[40,1051,216],{"class":210},[40,1053,176],{"class":98},[40,1055,334],{"class":210},[40,1057,223],{"class":98},[40,1059,339],{"class":210},[40,1061,176],{"class":98},[40,1063,344],{"class":210},[40,1065,661],{"class":98},[40,1067,1068],{"class":42,"line":237},[40,1069,373],{"class":98},[40,1071,1072],{"class":42,"line":265},[40,1073,125],{"emptyLinePlaceholder":124},[40,1075,1076,1078,1080],{"class":42,"line":293},[40,1077,674],{"class":98},[40,1079,134],{"class":94},[40,1081,679],{"class":98},[40,1083,1084,1086,1088],{"class":42,"line":321},[40,1085,684],{"class":98},[40,1087,134],{"class":94},[40,1089,1090],{"class":50}," \"Visitors vs Signups\"\n",[40,1092,1093,1095,1097],{"class":42,"line":349},[40,1094,694],{"class":98},[40,1096,134],{"class":94},[40,1098,1099],{"class":50}," \"Count\"\n",[40,1101,1102,1104,1106],{"class":42,"line":355},[40,1103,704],{"class":98},[40,1105,134],{"class":94},[40,1107,709],{"class":50},[40,1109,1110],{"class":42,"line":370},[40,1111,125],{"emptyLinePlaceholder":124},[40,1113,1114],{"class":42,"line":376},[40,1115,1116],{"class":87},"# Two metric columns (B and C) -> two series.\n",[40,1118,1119,1121,1123,1125,1127,1129,1131,1133,1136,1138,1141,1143,1145,1147,1149,1151,1153,1155,1157],{"class":42,"line":381},[40,1120,718],{"class":98},[40,1122,134],{"class":94},[40,1124,723],{"class":98},[40,1126,727],{"class":726},[40,1128,134],{"class":94},[40,1130,732],{"class":210},[40,1132,176],{"class":98},[40,1134,1135],{"class":726},"max_col",[40,1137,134],{"class":94},[40,1139,1140],{"class":210},"3",[40,1142,176],{"class":98},[40,1144,737],{"class":726},[40,1146,134],{"class":94},[40,1148,216],{"class":210},[40,1150,176],{"class":98},[40,1152,746],{"class":726},[40,1154,134],{"class":94},[40,1156,751],{"class":210},[40,1158,433],{"class":98},[40,1160,1161,1163,1165,1167,1169],{"class":42,"line":408},[40,1162,762],{"class":98},[40,1164,765],{"class":726},[40,1166,134],{"class":94},[40,1168,770],{"class":210},[40,1170,433],{"class":98},[40,1172,1173,1176,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196,1198],{"class":42,"line":419},[40,1174,1175],{"class":98},"chart.set_categories(Reference(ws, ",[40,1177,727],{"class":726},[40,1179,134],{"class":94},[40,1181,216],{"class":210},[40,1183,176],{"class":98},[40,1185,737],{"class":726},[40,1187,134],{"class":94},[40,1189,732],{"class":210},[40,1191,176],{"class":98},[40,1193,746],{"class":726},[40,1195,134],{"class":94},[40,1197,751],{"class":210},[40,1199,1200],{"class":98},"))\n",[40,1202,1203],{"class":42,"line":424},[40,1204,125],{"emptyLinePlaceholder":124},[40,1206,1207,1209,1211,1214,1216,1219,1222],{"class":42,"line":436},[40,1208,439],{"class":210},[40,1210,442],{"class":98},[40,1212,1213],{"class":50},"\"series:\"",[40,1215,176],{"class":98},[40,1217,1218],{"class":210},"len",[40,1220,1221],{"class":98},"(chart.series))   ",[40,1223,1224],{"class":87},"# -> 2, legend appears automatically\n",[40,1226,1227,1229,1231],{"class":42,"line":830},[40,1228,822],{"class":98},[40,1230,825],{"class":50},[40,1232,433],{"class":98},[40,1234,1235,1237,1240],{"class":42,"line":840},[40,1236,427],{"class":98},[40,1238,1239],{"class":50},"\"line_multi.xlsx\"",[40,1241,433],{"class":98},[10,1243,1244,1245,1247,1248,1251,1252,1255,1256,1260,1261,1263],{},"With more than one series the legend appears on its own. The key is that the value ",[37,1246,460],{}," spans ",[37,1249,1250],{},"min_col=2"," to ",[37,1253,1254],{},"max_col=3"," while the ",[1257,1258,1259],"strong",{},"category"," ",[37,1262,460],{}," stays on the single date column.",[25,1265,1267],{"id":1266},"step-4-a-date-axis-markers-and-smoothing","Step 4 — A date axis, markers, and smoothing",[10,1269,1270,1273,1274,1277],{},[37,1271,1272],{},"set_categories"," treats your dates as text labels. To get a true date-scaled axis — where uneven gaps between dates are spaced proportionally — switch the x-axis to ",[37,1275,1276],{},"dateAx",". Add markers so each data point is visible, and decide on smoothing.",[30,1279,1281],{"className":78,"code":1280,"language":80,"meta":35,"style":35},"# pip install openpyxl\nfrom datetime import date\nfrom openpyxl import Workbook\nfrom openpyxl.chart import LineChart, Reference\nfrom openpyxl.chart.axis import DateAxis\n\nwb = Workbook()\nws = wb.active\nws.append([\"Date\", \"Visitors\", \"Signups\"])\nfor r in [(date(2026, 1, 1), 1200, 90), (date(2026, 1, 8), 1340, 110),\n          (date(2026, 1, 15), 1290, 105), (date(2026, 1, 22), 1510, 130),\n          (date(2026, 1, 29), 1625, 142)]:\n    ws.append(r)\nfor cell in ws[\"A\"][1:]:\n    cell.number_format = \"yyyy-mm-dd\"\n\nchart = LineChart()\nchart.title = \"Weekly Traffic\"\nchart.x_axis = DateAxis(crossAx=100)   # treat categories as real dates\nchart.x_axis.number_format = \"yyyy-mm-dd\"\nchart.x_axis.majorTimeUnit = \"days\"\nchart.x_axis.title = \"Date\"\nchart.y_axis.title = \"Count\"\n\ndata = Reference(ws, min_col=2, max_col=3, min_row=1, max_row=6)\nchart.add_data(data, titles_from_data=True)\nchart.set_categories(Reference(ws, min_col=1, min_row=2, max_row=6))\n\nfor s in chart.series:\n    s.smooth = False          # straight segments; True for curved\n    s.marker.symbol = \"circle\"\n    s.marker.size = 7\n\nws.add_chart(chart, \"E2\")\nwb.save(\"line_dateaxis.xlsx\")\nprint(\"Saved line_dateaxis.xlsx with a date axis and markers\")\n",[37,1282,1283,1287,1297,1307,1317,1329,1333,1341,1349,1365,1415,1459,1483,1487,1506,1514,1518,1526,1535,1558,1567,1577,1586,1594,1598,1638,1650,1679,1684,1697,1711,1722,1733,1738,1747,1757],{"__ignoreMap":35},[40,1284,1285],{"class":42,"line":43},[40,1286,88],{"class":87},[40,1288,1289,1291,1293,1295],{"class":42,"line":91},[40,1290,95],{"class":94},[40,1292,99],{"class":98},[40,1294,102],{"class":94},[40,1296,105],{"class":98},[40,1298,1299,1301,1303,1305],{"class":42,"line":108},[40,1300,95],{"class":94},[40,1302,113],{"class":98},[40,1304,102],{"class":94},[40,1306,118],{"class":98},[40,1308,1309,1311,1313,1315],{"class":42,"line":121},[40,1310,95],{"class":94},[40,1312,497],{"class":98},[40,1314,102],{"class":94},[40,1316,502],{"class":98},[40,1318,1319,1321,1324,1326],{"class":42,"line":128},[40,1320,95],{"class":94},[40,1322,1323],{"class":98}," openpyxl.chart.axis ",[40,1325,102],{"class":94},[40,1327,1328],{"class":98}," DateAxis\n",[40,1330,1331],{"class":42,"line":140},[40,1332,125],{"emptyLinePlaceholder":124},[40,1334,1335,1337,1339],{"class":42,"line":151},[40,1336,131],{"class":98},[40,1338,134],{"class":94},[40,1340,137],{"class":98},[40,1342,1343,1345,1347],{"class":42,"line":162},[40,1344,143],{"class":98},[40,1346,134],{"class":94},[40,1348,148],{"class":98},[40,1350,1351,1353,1355,1357,1359,1361,1363],{"class":42,"line":167},[40,1352,170],{"class":98},[40,1354,173],{"class":50},[40,1356,176],{"class":98},[40,1358,179],{"class":50},[40,1360,176],{"class":98},[40,1362,184],{"class":50},[40,1364,539],{"class":98},[40,1366,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1399,1401,1403,1405,1407,1409,1411,1413],{"class":42,"line":193},[40,1368,358],{"class":94},[40,1370,361],{"class":98},[40,1372,364],{"class":94},[40,1374,550],{"class":98},[40,1376,211],{"class":210},[40,1378,176],{"class":98},[40,1380,216],{"class":210},[40,1382,176],{"class":98},[40,1384,216],{"class":210},[40,1386,223],{"class":98},[40,1388,226],{"class":210},[40,1390,176],{"class":98},[40,1392,231],{"class":210},[40,1394,571],{"class":98},[40,1396,211],{"class":210},[40,1398,176],{"class":98},[40,1400,216],{"class":210},[40,1402,176],{"class":98},[40,1404,250],{"class":210},[40,1406,223],{"class":98},[40,1408,255],{"class":210},[40,1410,176],{"class":98},[40,1412,260],{"class":210},[40,1414,234],{"class":98},[40,1416,1417,1419,1421,1423,1425,1427,1429,1431,1433,1435,1437,1439,1441,1443,1445,1447,1449,1451,1453,1455,1457],{"class":42,"line":204},[40,1418,596],{"class":98},[40,1420,211],{"class":210},[40,1422,176],{"class":98},[40,1424,216],{"class":210},[40,1426,176],{"class":98},[40,1428,278],{"class":210},[40,1430,223],{"class":98},[40,1432,283],{"class":210},[40,1434,176],{"class":98},[40,1436,288],{"class":210},[40,1438,571],{"class":98},[40,1440,211],{"class":210},[40,1442,176],{"class":98},[40,1444,216],{"class":210},[40,1446,176],{"class":98},[40,1448,306],{"class":210},[40,1450,223],{"class":98},[40,1452,311],{"class":210},[40,1454,176],{"class":98},[40,1456,316],{"class":210},[40,1458,234],{"class":98},[40,1460,1461,1463,1465,1467,1469,1471,1473,1475,1477,1479,1481],{"class":42,"line":237},[40,1462,596],{"class":98},[40,1464,211],{"class":210},[40,1466,176],{"class":98},[40,1468,216],{"class":210},[40,1470,176],{"class":98},[40,1472,334],{"class":210},[40,1474,223],{"class":98},[40,1476,339],{"class":210},[40,1478,176],{"class":98},[40,1480,344],{"class":210},[40,1482,661],{"class":98},[40,1484,1485],{"class":42,"line":265},[40,1486,373],{"class":98},[40,1488,1489,1491,1493,1495,1497,1499,1501,1503],{"class":42,"line":293},[40,1490,358],{"class":94},[40,1492,386],{"class":98},[40,1494,364],{"class":94},[40,1496,391],{"class":98},[40,1498,394],{"class":50},[40,1500,397],{"class":98},[40,1502,216],{"class":210},[40,1504,1505],{"class":98},":]:\n",[40,1507,1508,1510,1512],{"class":42,"line":321},[40,1509,411],{"class":98},[40,1511,134],{"class":94},[40,1513,416],{"class":50},[40,1515,1516],{"class":42,"line":349},[40,1517,125],{"emptyLinePlaceholder":124},[40,1519,1520,1522,1524],{"class":42,"line":355},[40,1521,674],{"class":98},[40,1523,134],{"class":94},[40,1525,679],{"class":98},[40,1527,1528,1530,1532],{"class":42,"line":370},[40,1529,684],{"class":98},[40,1531,134],{"class":94},[40,1533,1534],{"class":50}," \"Weekly Traffic\"\n",[40,1536,1537,1540,1542,1545,1548,1550,1553,1555],{"class":42,"line":376},[40,1538,1539],{"class":98},"chart.x_axis ",[40,1541,134],{"class":94},[40,1543,1544],{"class":98}," DateAxis(",[40,1546,1547],{"class":726},"crossAx",[40,1549,134],{"class":94},[40,1551,1552],{"class":210},"100",[40,1554,754],{"class":98},[40,1556,1557],{"class":87},"# treat categories as real dates\n",[40,1559,1560,1563,1565],{"class":42,"line":381},[40,1561,1562],{"class":98},"chart.x_axis.number_format ",[40,1564,134],{"class":94},[40,1566,416],{"class":50},[40,1568,1569,1572,1574],{"class":42,"line":408},[40,1570,1571],{"class":98},"chart.x_axis.majorTimeUnit ",[40,1573,134],{"class":94},[40,1575,1576],{"class":50}," \"days\"\n",[40,1578,1579,1581,1583],{"class":42,"line":419},[40,1580,704],{"class":98},[40,1582,134],{"class":94},[40,1584,1585],{"class":50}," \"Date\"\n",[40,1587,1588,1590,1592],{"class":42,"line":424},[40,1589,694],{"class":98},[40,1591,134],{"class":94},[40,1593,1099],{"class":50},[40,1595,1596],{"class":42,"line":436},[40,1597,125],{"emptyLinePlaceholder":124},[40,1599,1600,1602,1604,1606,1608,1610,1612,1614,1616,1618,1620,1622,1624,1626,1628,1630,1632,1634,1636],{"class":42,"line":830},[40,1601,718],{"class":98},[40,1603,134],{"class":94},[40,1605,723],{"class":98},[40,1607,727],{"class":726},[40,1609,134],{"class":94},[40,1611,732],{"class":210},[40,1613,176],{"class":98},[40,1615,1135],{"class":726},[40,1617,134],{"class":94},[40,1619,1140],{"class":210},[40,1621,176],{"class":98},[40,1623,737],{"class":726},[40,1625,134],{"class":94},[40,1627,216],{"class":210},[40,1629,176],{"class":98},[40,1631,746],{"class":726},[40,1633,134],{"class":94},[40,1635,751],{"class":210},[40,1637,433],{"class":98},[40,1639,1640,1642,1644,1646,1648],{"class":42,"line":840},[40,1641,762],{"class":98},[40,1643,765],{"class":726},[40,1645,134],{"class":94},[40,1647,770],{"class":210},[40,1649,433],{"class":98},[40,1651,1653,1655,1657,1659,1661,1663,1665,1667,1669,1671,1673,1675,1677],{"class":42,"line":1652},27,[40,1654,1175],{"class":98},[40,1656,727],{"class":726},[40,1658,134],{"class":94},[40,1660,216],{"class":210},[40,1662,176],{"class":98},[40,1664,737],{"class":726},[40,1666,134],{"class":94},[40,1668,732],{"class":210},[40,1670,176],{"class":98},[40,1672,746],{"class":726},[40,1674,134],{"class":94},[40,1676,751],{"class":210},[40,1678,1200],{"class":98},[40,1680,1682],{"class":42,"line":1681},28,[40,1683,125],{"emptyLinePlaceholder":124},[40,1685,1687,1689,1692,1694],{"class":42,"line":1686},29,[40,1688,358],{"class":94},[40,1690,1691],{"class":98}," s ",[40,1693,364],{"class":94},[40,1695,1696],{"class":98}," chart.series:\n",[40,1698,1700,1703,1705,1708],{"class":42,"line":1699},30,[40,1701,1702],{"class":98},"    s.smooth ",[40,1704,134],{"class":94},[40,1706,1707],{"class":210}," False",[40,1709,1710],{"class":87},"          # straight segments; True for curved\n",[40,1712,1714,1717,1719],{"class":42,"line":1713},31,[40,1715,1716],{"class":98},"    s.marker.symbol ",[40,1718,134],{"class":94},[40,1720,1721],{"class":50}," \"circle\"\n",[40,1723,1725,1728,1730],{"class":42,"line":1724},32,[40,1726,1727],{"class":98},"    s.marker.size ",[40,1729,134],{"class":94},[40,1731,1732],{"class":210}," 7\n",[40,1734,1736],{"class":42,"line":1735},33,[40,1737,125],{"emptyLinePlaceholder":124},[40,1739,1741,1743,1745],{"class":42,"line":1740},34,[40,1742,822],{"class":98},[40,1744,825],{"class":50},[40,1746,433],{"class":98},[40,1748,1750,1752,1755],{"class":42,"line":1749},35,[40,1751,427],{"class":98},[40,1753,1754],{"class":50},"\"line_dateaxis.xlsx\"",[40,1756,433],{"class":98},[40,1758,1760,1762,1764,1767],{"class":42,"line":1759},36,[40,1761,439],{"class":210},[40,1763,442],{"class":98},[40,1765,1766],{"class":50},"\"Saved line_dateaxis.xlsx with a date axis and markers\"",[40,1768,433],{"class":98},[10,1770,1771,1774,1775,1777],{},[37,1772,1773],{},"DateAxis"," requires the category cells to hold real dates (Step 1) — that is why the data was written with ",[37,1776,74],{}," objects rather than strings. With a plain text axis, January 1 and January 29 would be equally spaced regardless of the real gap; the date axis spaces them by actual time.",[25,1779,1781],{"id":1780},"common-pitfalls","Common pitfalls",[1783,1784,1785,1801],"table",{},[1786,1787,1788],"thead",{},[1789,1790,1791,1795,1798],"tr",{},[1792,1793,1794],"th",{},"Symptom",[1792,1796,1797],{},"Cause",[1792,1799,1800],{},"Fix",[1802,1803,1804,1822,1839,1854,1878,1898],"tbody",{},[1789,1805,1806,1810,1813],{},[1807,1808,1809],"td",{},"X-axis ignores date spacing",[1807,1811,1812],{},"Dates stored as strings, or axis left as default category axis",[1807,1814,1815,1816,1818,1819,23],{},"Write ",[37,1817,74],{}," values and assign ",[37,1820,1821],{},"chart.x_axis = DateAxis(crossAx=100)",[1789,1823,1824,1827,1833],{},[1807,1825,1826],{},"Only one line appears for two metrics",[1807,1828,1829,1830,1832],{},"Value ",[37,1831,460],{}," covers one column",[1807,1834,1835,1836,1838],{},"Widen it with ",[37,1837,1135],{}," to span every metric column.",[1789,1840,1841,1844,1849],{},[1807,1842,1843],{},"The date column itself plotted as a line",[1807,1845,1846,1847],{},"Date column included in the value ",[37,1848,460],{},[1807,1850,1851,1852,23],{},"Keep dates out of the values — put them only in ",[37,1853,1272],{},[1789,1855,1856,1859,1865],{},[1807,1857,1858],{},"Series named \"Series 1\", \"Series 2\"",[1807,1860,1861,1862,1864],{},"Header row omitted or ",[37,1863,765],{}," not set",[1807,1866,1867,1868,1870,1871,1874,1875,23],{},"Start the value ",[37,1869,460],{}," at ",[37,1872,1873],{},"min_row=1"," and pass ",[37,1876,1877],{},"titles_from_data=True",[1789,1879,1880,1883,1888],{},[1807,1881,1882],{},"Last data point missing",[1807,1884,1885,1887],{},[37,1886,746],{}," off by one",[1807,1889,1890,1891,1894,1895,23],{},"With a header plus N rows, ",[37,1892,1893],{},"max_row = N + 1",". Five rows → ",[37,1896,1897],{},"max_row=6",[1789,1899,1900,1903,1906],{},[1807,1901,1902],{},"No markers on the line",[1807,1904,1905],{},"Markers off by default in openpyxl",[1807,1907,1908,1909,1912],{},"Set ",[37,1910,1911],{},"series.marker.symbol = \"circle\""," per series.",[25,1914,1916],{"id":1915},"performance-and-scale","Performance and scale",[10,1918,1919],{},"The chart definition is tiny and fixed in size; only the underlying cells scale with the data. A line chart stays readable far longer than a bar chart — hundreds of points per series are fine — but past a few thousand points the rendered line turns to noise, so downsample or aggregate (for example to weekly or monthly buckets) before plotting. Writing the series data is the only per-row cost, and it is negligible at report scale.",[25,1921,1923],{"id":1922},"frequently-asked-questions","Frequently asked questions",[10,1925,1926,1929,1930,1932],{},[1257,1927,1928],{},"Why are my dates evenly spaced even though the real gaps differ?"," You are on a category axis, which treats every label as equal. Switch to ",[37,1931,1773],{}," and make sure the cells hold real date values.",[10,1934,1935,1938,1939,1942,1943,1946,1947,1950,1951,23],{},[1257,1936,1937],{},"How do I add a second y-axis for a series on a different scale?"," Create a second ",[37,1940,1941],{},"LineChart",", add the other series to it, set its ",[37,1944,1945],{},"y_axis.axId"," to a new value and ",[37,1948,1949],{},"y_axis.crosses = \"max\"",", then combine with ",[37,1952,1953],{},"chart += chart2",[10,1955,1956,1959,1960,1963,1964,1966,1967,1970],{},[1257,1957,1958],{},"Can I mix a line and bars in one chart?"," Yes — build a ",[37,1961,1962],{},"BarChart"," and a ",[37,1965,1941],{},", then add them together with ",[37,1968,1969],{},"chart1 += chart2",". The combined chart keeps both renderings.",[10,1972,1973,1976,1977,1980,1981,1984],{},[1257,1974,1975],{},"Should I use smoothing?"," Usually no. Smoothing (",[37,1978,1979],{},"series.smooth = True",") draws curves between points that imply values you don't have. Leave it ",[37,1982,1983],{},"False"," for honest reporting.",[25,1986,1988],{"id":1987},"conclusion","Conclusion",[10,1990,1991,1992,1994,1995,1997,1998,2000,2001,2003],{},"A line chart for a report is the same Reference-and-categories pattern as any openpyxl chart, with two time-series specifics: write real ",[37,1993,74],{}," values so you can promote the x-axis to a ",[37,1996,1773],{},", and widen the value ",[37,1999,460],{}," across columns to get one line per metric. Keep the date column out of the values, get ",[37,2002,746],{}," right, and add markers so individual points stay visible.",[25,2005,2007],{"id":2006},"where-to-go-next","Where to go next",[2009,2010,2011,2017,2023],"ul",{},[2012,2013,2014,2015],"li",{},"Up to the cluster: ",[14,2016,17],{"href":16},[2012,2018,2019,2020],{},"The sibling guide: ",[14,2021,2022],{"href":21},"Create a Bar Chart in Excel with openpyxl",[2012,2024,2025,2026],{},"Related: ",[14,2027,2029],{"href":2028},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002F","Building Multi-Sheet Excel Dashboards",[2031,2032,2033],"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":35,"searchDepth":91,"depth":91,"links":2035},[2036,2037,2038,2039,2040,2041,2042,2043,2044,2045],{"id":27,"depth":91,"text":28},{"id":67,"depth":91,"text":68},{"id":453,"depth":91,"text":454},{"id":861,"depth":91,"text":862},{"id":1266,"depth":91,"text":1267},{"id":1780,"depth":91,"text":1781},{"id":1915,"depth":91,"text":1916},{"id":1922,"depth":91,"text":1923},{"id":1987,"depth":91,"text":1988},{"id":2006,"depth":91,"text":2007},"Add an editable line chart to an Excel report with openpyxl: write time-series data, plot multiple series, set a date x-axis, add markers, label axes, and anchor it.","md",{},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python",{"title":2051,"description":2052},"Add a Line Chart to an Excel Report in Python","Build an openpyxl line chart for time-series data: plot multiple series from Reference ranges, set a date x-axis, add markers and smoothing, label axes, and anchor it.","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-line-chart-to-excel-report-with-python\u002Findex","3Qgq5NcCY3e5u_xcEqWrvZDbZBlEsDZp5AM7MYxxEkM",[2056,2059],{"title":17,"path":2057,"stem":2058,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl","formatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Findex",{"title":2022,"path":2060,"stem":2061,"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",1781773161042]