

python、openpyxlを利用して、積上げ棒・折れ線グラフを一つのグラフエリアに表示する「複合グラフ」を作成したいです。対応方法について、ご教授願います。  
また、そもそもopenpyxlを使用した場合は複合グラフの作成はサポートされていないのでしょうか？

### Python（3.8.2）コード

[code]

    import openpyxl
    from openpyxl.chart import BarChart, LineChart, Reference
    from openpyxl.chart.plotarea import DataTable
    
    wb = openpyxl.load_workbook("./sample.xlsx")
    sh = wb['list']
    
    labels = Reference(sh, min_col=1, max_col=1, min_row=3, max_row=sh.max_row)
    data1 = Reference(sh, min_col=2, max_col=6, min_row=2, max_row=sh.max_row)
    data2 = Reference(sh, min_col=5, max_col=6, min_row=2, max_row=sh.max_row)
    chart = BarChart()
    chart.type = "col"
    chart.grouping = "stacked"
    
    chart.overlap = 100
    chart.title = "メインタイトル"
    chart.y_axis.title = "数量"
    chart.legend.position = 'b'
    chart.add_data(data1, titles_from_data=True)
    chart.set_categories(labels)
    
    chart2 = LineChart()
    chart2.add_data(data2, titles_from_data=True)
    
    chart.height = 10
    chart.width = 15
    
    # datatable
    chart.plot_area.dTable = DataTable()
    chart.plot_area.dTable.showHorzBorder = True
    chart.plot_area.dTable.showVertBorder = True
    chart.plot_area.dTable.showOutline = True
    chart.plot_area.dTable.showKeys = True
    
    sh.add_chart(chart, "I2")
    sh.add_chart(chart2, "I20")
    
    wb.save("./sample.xlsx")
    
[/code]

### グラフ作成時の入力データ

[code]

        title               
    date    100-10  200-10  300-10  gokei   base
    9/16    15  48  41  104 50
    9/17    15  48  46  109 50
    9/18    15  50  50  115 50
    9/19    15  50  49  114 50
    9/20    15  49  49  113 50
    
[/code]

※"100-10","200-10","300-10"を積上げ棒グラフ  
※"gokei","base"を折れ線グラフ  
※最終的には"gokei"の折れ線グラフを非表示にし、データラベルの設定を実施したい

### 確認したこと

  * グラフ単体で作成できることを確認
  * グラフが複数作成できることを確認


CC BY-SA 4.0
2021-09-20T07:08:09.190
82598
2023-09-21T12:04:15.500
2021-09-20T08:00:32.197
3060
48290
question
python python3 openpyxl
python、openpyxl利用して複合グラフを作成したい


グラフを重ね合わせるならこちらのページ [Adding a second
axis](https://openpyxl.readthedocs.io/en/stable/charts/secondary.html) の`c1 +=
c2`にあるように、質問のソースでは`chart += chart2`で出来るでしょう。

その上で以下2点は表示するデータの列を調節することで出来るでしょう。

> ※"100-10","200-10","300-10"を積上げ棒グラフ  
>  ※"gokei","base"を折れ線グラフ

以下のように出来ると思われます。`####`を付けたところが変更点

[code]

    import openpyxl
    from openpyxl.chart import BarChart, LineChart, Reference
    from openpyxl.chart.plotarea import DataTable
    
    wb = openpyxl.load_workbook("./sample.xlsx")
    sh = wb['list']
    
    labels = Reference(sh, min_col=1, max_col=1, min_row=3, max_row=sh.max_row)
    #### data1 = Reference(sh, min_col=2, max_col=6, min_row=2, max_row=sh.max_row)
    #### data2 = Reference(sh, min_col=5, max_col=6, min_row=2, max_row=sh.max_row)
    data1 = Reference(sh, min_col=2, max_col=4, min_row=2, max_row=sh.max_row) #### ※"100-10","200-10","300-10"を積上げ棒グラフ
    data2 = Reference(sh, min_col=5, max_col=6, min_row=2, max_row=sh.max_row) #### ※"gokei","base"を折れ線グラフ
    chart = BarChart()
    chart.type = "col"
    chart.grouping = "stacked"
    
    chart.overlap = 100
    chart.title = "メインタイトル"
    chart.y_axis.title = "数量"
    chart.legend.position = 'b'
    chart.add_data(data1, titles_from_data=True)
    chart.set_categories(labels)
    
    chart2 = LineChart()
    chart2.add_data(data2, titles_from_data=True)
    
    chart.height = 10
    chart.width = 15
    
    # datatable
    chart.plot_area.dTable = DataTable()
    chart.plot_area.dTable.showHorzBorder = True
    chart.plot_area.dTable.showVertBorder = True
    chart.plot_area.dTable.showOutline = True
    chart.plot_area.dTable.showKeys = True
    
    chart += chart2 #### 複合グラフ
    
    sh.add_chart(chart, "I2")
    #### sh.add_chart(chart2, "I20") #### 2つ目の単独は表示しない
    
    wb.save("./sample.xlsx")
    
[/code]

* * *

その上で、以下については`DataLabelList`というものを使えば出来ると思われます。  
グラフの非表示は出来るのかもしれませんが、直ぐには見当たらなかったので、最小サイズの点だけ表示して、連結の線が無いようにしてみました。

> ※最終的には"gokei"の折れ線グラフを非表示にし、データラベルの設定を実施したい

この質問で直接参考になるかは疑問ですが、良い資料にはなるでしょう。  
[Pythonライブラリ(openpyxl)でExcelのグラフを作成する方法【徹底解説】](https://www.shibutan-
bloomers.com/python_libraly_openpyxl-8/2947/)  
[Pythonライブラリ(openpyxl)によるExcel「棒(縦棒・横棒)グラフ」の作り方とデザインレシピ【徹底解説】](https://www.shibutan-
bloomers.com/python_libraly_openpyxl-10/3260/)

こちらはOpenPyXlではなくExcelだけでやる場合の記事でしょう。  
[Add Total Values for Stacked Column and Stacked Bar Charts in
Excel](https://anthonysmoak.com/2020/12/29/add-total-values-for-stacked-
column-and-stacked-bar-charts-in-excel/)

OpenPyXlではこの辺が参考になるでしょう。  
[Line Charts](https://openpyxl.readthedocs.io/en/stable/charts/line.html)  
[class
openpyxl.chart.marker.Marker](https://openpyxl.readthedocs.io/en/stable/api/openpyxl.chart.marker.html#openpyxl.chart.marker.Marker)  
[class
openpyxl.chart.label.DataLabelList](https://openpyxl.readthedocs.io/en/stable/api/openpyxl.chart.label.html?highlight=datalabellist#openpyxl.chart.label.DataLabelList)

最初のものに追加/変更して以下のようにしてみました。

[code]

    import openpyxl
    from openpyxl.chart import BarChart, LineChart, Reference
    from openpyxl.chart.label import DataLabel, DataLabelList
    from openpyxl.chart.plotarea import DataTable
    
    wb = openpyxl.load_workbook("./sample.xlsx")
    sh = wb['list']
    
    labels = Reference(sh, min_col=1, max_col=1, min_row=3, max_row=sh.max_row)
    #### data1 = Reference(sh, min_col=2, max_col=6, min_row=2, max_row=sh.max_row)
    #### data2 = Reference(sh, min_col=5, max_col=6, min_row=2, max_row=sh.max_row)
    data1 = Reference(sh, min_col=2, max_col=4, min_row=2, max_row=sh.max_row) #### ※"100-10","200-10","300-10"を積上げ棒グラフ
    #### "gokei"と"base"の表示形式を分けるために分割 ####
    data2 = Reference(sh, min_col=5, max_col=5, min_row=2, max_row=sh.max_row) #### ※"gokei"を折れ線グラフ
    data3 = Reference(sh, min_col=6, max_col=6, min_row=2, max_row=sh.max_row) #### ※"base"を折れ線グラフ
    chart = BarChart()
    chart.type = "col"
    chart.grouping = "stacked"
    
    chart.overlap = 100
    chart.title = "メインタイトル"
    chart.y_axis.title = "数量"
    chart.legend.position = 'b'
    chart.add_data(data1, titles_from_data=True)
    chart.set_categories(labels)
    
    chart2 = LineChart() #### "gokei"
    chart2.add_data(data2, titles_from_data=True)
    
    chart3 = LineChart() #### "base"
    chart3.add_data(data3, titles_from_data=True) ####
    
    chart.height = 10
    chart.width = 15
    
    # datatable
    chart.plot_area.dTable = DataTable()
    chart.plot_area.dTable.showHorzBorder = True
    chart.plot_area.dTable.showVertBorder = True
    chart.plot_area.dTable.showOutline = True
    chart.plot_area.dTable.showKeys = True
    
    #### "gokei" を最小サイズの点で表示し、連結の線を表示せず、数値をラベル表示する
    s1 = chart2.series[0]
    s1.marker.symbol = "dot"
    s1.marker.size   = 2
    s1.graphicalProperties.line.noFill = True
    chart2.dataLabels = DataLabelList(dLblPos='t')
    chart2.dataLabels.showVal = True
    #### ここまで
    
    chart += chart2 #### "gokei"を合成
    chart += chart3 #### "base"を合成
    
    sh.add_chart(chart, "I2")
    #### sh.add_chart(chart2, "I20") #### 2つ目の単独は表示しない
    
    wb.save("./sample.xlsx")
    
[/code]


CC BY-SA 4.0
2021-09-20T12:40:56.923
82604
2021-09-20T12:40:56.923
26370
82598
answer