3 Python で Excel のグラフ作成 (Windows編)

Index

3-1: ChartWizard を使った単純なグラフ

Pythonを使って、MicrosoftのExcelのグラフを作る方法を紹介します。 ネットで調べたところ、グラフのオブジェクトの ChartWizard というメソッドを使えばわりと簡単にできるようです。

まず、最小限の例です。 次のスクリプトを実行すると、グラフのみのシートが追加されて下の画像のグラフができます。

サンプルグラフ01
import win32com.client
import os.path

MyData = ( ('Name','Value'), ('A',5), ('B',2), ('C',3), ('D',7), )
MyRange = "A1:B5"

#Run Excel
xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible = 1
xlApp.Workbooks.Add()
xlSheet = xlApp.Workbooks(1).Sheets(1)

#Input Data
DataRange = xlSheet.Range(MyRange)
DataRange.Value = MyData

#Draw Graph
xlChart = xlApp.Charts.Add()
xlChart.ChartWizard(Source = DataRange, Gallery = 3, Format = None,
        PlotBy = 2, CategoryLabels = 1, SeriesLabels = 1, HasLegend = 1,
        Title = 'Sample01', CategoryTitle = 'Name', ValueTitle = 'Value',)

#Save File
FileName = 'PyExcGrp01.xls'
FilePath = os.path.join(os.path.dirname(__file__), FileName)

xlApp.Workbooks(1).SaveAs(FilePath)
xlApp.Quit()

スクリプトの中で、Excelの起動(#Run Excel)、データ入力(#Input Data)、ファイル保存(#Save File)、は、 「1: PythonでExcelの初歩的な操作」で説明してます。 ここで解説するのは、#Draw Graph の部分です。

xlChart = xlApp.Charts.Add()」 でグラフオブジェクト xlChart が作られます。 xlChartChartWizardメソッドの設定でグラフが描かれます。 この説明を次にします。

3-2: ChartWizardの引数

ChartWizardの引数は、次のようになります。

引数名意味
Sourceグラフのデータの範囲
Galleryグラフのタイプ
Formatグラフのサブタイプ
PlotByデータが横方向か縦方向かの指定
CategoryLabelsカテゴリーが入力されている行または列番号
SeriesLabelsシリーズが入力されている行または列番号
HasLegend1なら凡例を表示する。0なら表示しない
Titleグラフのタイトル
CategoryTitleカテゴリーのタイトル
ValueTitle値のタイトル
ExtraTitle他のタイトル

以下、それぞれの引数の説明をします。

3-2-1: Source

グラフに表示したいデータの範囲オブジェクトを指定します。

3-2-2: Gallery, Format

引数 Gallery には、棒グラフ、折れ線グラフ、円グラフなど、グラフのタイプを数値で指定します。具体的には次のようになります。

グラフタイプ数値Visual Basicでの名前注意
面グラフ1xlArea
集合横棒グラフ2xlBarClustered
集合縦棒グラフ3xlColumnClustered
折れ線グラフ4xlLine
円グラフ5xlPie一番目の系列だけ表示する
レーダーグラフ6xlRadar
散布図7xlXYScatter
縦棒と折れ線8---系列がひとつならば縦棒のみ
3D面グラフ9xl3DArea
3D横棒グラフ10xl3DBarClustered
3D縦棒グラフ11xl3DColumn
3D折れ線グラフ12xl3DLine
3D円グラフ13xl3DPie
3D等高線14xlSurface系列がひとつならばエラー
ドーナツグラフ15xlDoughnut

引数 Format は、Visual Basic だと数値を設定することで他のグラフタイプにできますが、 Python だと適当に入れても変化ありません。 かといって省略するとエラーでグラフが描かれないので、 「Format = None」としておくのが無難です。 まだ研究の余地があります。

3-2-3: PlotBy, CategoryLabels, SeriesLabels

これらの引数は、元データの表の行と列の意味に関係があります。 上のスクリプト例で作られる表は、

NameValue
A5
B2
C3
D7

という感じになってます。 ここでは、(最初の行以外の)行が1つのレコード(物、人、日時、場所など)を表し、 列はフィ−ルド(名前、個数、値段、年齢、身長、点数、気温など)を表しています。 ひとつの列がひとつの「系列」になります。 こういう方向で作られた表の場合は、PlotBy = 2 とします。 ここの説明では、この方向で作られた表のみを扱います。
こうじゃなく、行列の方向(意味)が入れ替わってる場合は、PlotBy = 1 になります。 1, 2 の意味は Visual Basic の定数で 1が xlRows、2が xlColumns のことです。

もっと正確な言い方はあるでしょうけど、普段Excelは使ってないのでなんと言っていいのかわかりません。 例えば「行が並んでる方向」といった簡単そうな言葉でも、人によって解釈は違うかも知れません。 ひとつの行は横向きですけど、複数の行は縦方向に増えて並んでます。 そうすると「行が並んでる方向」は、横なのか縦なのか、どっちの解釈もありえます。

CategoryLabels は、「個々のレコードの名前」がある列番号(行列が入れ替わってれば行番号)を指定します。 上の表で「A, B, C, D」がある列番号で、実際の棒グラフでは棒の下に表示させる名前になります。

SeriesLabels は、「系列名(フィールド名、項目名)」がある行番号(行列が入れ替わってれば列番号)を指定します。 上の表で「Name, Value」がある行番号で、実際の棒グラフでは凡例の部分に表示される名前を含んだ行を指定します。 この行が無い場合は値は SeriesLabels = 0 とします。

3-2-4: HasLegend

1(または True)なら凡例を表示します。0(または False)なら表示しません。

3-2-5: Title, CategoryTitle, ValueTitle, ExtraTitle

Title はグラフのタイトルで、上の例だとグラフの上に表示されます。
CategoryTitle はカテゴリー(項目)のタイトルで、上の例だとグラフの横軸の下に表示されます。
ValueTitle は値のタイトルで、上の例だとグラフの縦軸の下に表示されます。
ExtraTitle は・・・、上のスクリプトに追加で設定しても表示されない(見えない)のでよくわかりません。

3-3: 単純な例

3-3-1: いろいろなギャラリー

最初のスクリプトの ChartWizardGallery 部分のみを書き換えた例をいくつか作ってみます。

3-3-1-1: 3D円グラフ (Gallery = 13)

凡例がABCDになってます。

サンプルグラフ02

3-3-1-2: レーダーグラフ (Gallery = 6)

一見、XY直交座標軸に見えますが、ABCDの4個の値なので四方に伸びてます。

サンプルグラフ03

3-3-1-3: 3D面グラフ (Gallery = 9)

サンプルグラフ04

3-3-2: 複数系列のグラフ

今までの例は、('A',5), ('B',2) ・・・と、A, B ・・・それぞれに対して値が一つだけでした。 言いかえると、5,2,3,7 と変化する系列が一つだけでした。 これを、系列が複数ある例を作ります。最初のスクリプトの、MyData, MyRange

MyData = (('A',5,3), ('B',2,6), ('C',3,5), ('D',7,3), ('E',2,4), )
MyRange = "A1:C5"

と置き換えて、グラフの Galleryをいくつか作ってみます。

3-3-2-1: 縦棒と折れ線 (Gallery = 8)

系列1が棒グラフで目盛は左側、系列2が折れ線グラフで目盛は右側になります。

サンプルグラフ05

3-3-2-2: 3D等高線 (Gallery = 14)

ぱっと見ても何が何だかわかりません。 もっとデータが多くて目の細かい連続的なグラフにならないと意味が無いようです。

サンプルグラフ06

3-3-2-3: ドーナツグラフ (Gallery = 15)

サンプルグラフ07

3-4: Sheet上への配置

これまでは、グラフだけのシートが作られてそこに表示されてましたが、 通常のシートに描く方法を説明します。 最初のスクリプトの、#Draw Graph の部分だけを書き換えて、他は同じです。 ChartWizardメソッドの引数名は省略してます。

サンプルグラフ08
#Draw Graph
xlChart = xlApp.Charts.Add()
xlChart.ChartWizard(DataRange, 2, None, 2, 1, 1, 1,'Sample01', 'Name', 'Value','Extra')

xlChart.Location(2, "Sheet1")    #Sheet1に表示する
xlChartObj = xlSheet.ChartObjects(1)
CellC2 = xlSheet.Cells(2,3)    #セルC2を基準に使う
xlChartObj.Left, xlChartObj.Top = CellC2.Left, CellC2.Top    #位置の設定
xlChartObj.Width, xlChartObj.Height= CellC2.Left * 2, CellC2.Height * 10  #縦横サイズの設定

シートにグラフを描くのは、xlChart.Location(2, "Sheet1") の部分です。 ここで引数の「2」は、Visual Basic での「xlLocationAsObject」の意味になります。 「"Sheet1"」がグラフを表示させたいシートになります。
が、しかし!!、これらの設定に関係なく一番上のシートに描かれてしまうようです。 一番上以外のシートに描きたい場合は、

  1. 描きたいシートをあらかじめ一番上に移動する
  2. グラフを描く
  3. 描かれたシートを元の位置に移動する

という方法になります。具体的には、

xlSheet2.Move(xlSheet1)
xlChart.Location(2, xlSheet2.Name)
xlSheet2.Move(None, xlSheet1)

となります。 ここでシートのメソッド Move の引数は、1個だけだとその引数のシートの前に移動します。 引数のシートの後ろに移動させたい場合は (None, xlSheet1)と指定します。 Visual Basic のリファレンスを見ると、Move(After = xlSheet1) でできそうなんですが、これが上手くいきません・・・。

話を戻して、グラフの位置は xlChartObj.Left, xlChartObj.Top、 サイズは xlChartObj.Width, xlChartObj.Height に数値を入れて設定します。 上の例では、シートのセルの位置と大きさに合わせてます。

これでシートに自由に配置できますが、サイズを縮小すると中のグラフ本体や文字も縮小されてしまいます。 このグラフ本体などの設定について、次に解説します。

3-5: グラフ要素の設定

ここでは、グラフ本体やラベルなどの設定を解説します。

3-5-1: PlotArea

勝手に「グラフ本体」と言ってますが、具体的には Excel で PlotArea というオブジェクトのことです。 まず、グラフ本体の位置とサイズを変更します。 具体的には次のスクリプトになります (まだ見た目が悪いのはおいておきます・・)

サンプルグラフ09
#Draw Graph
xlChart = xlApp.Charts.Add()
xlChart.ChartWizard(DataRange, 5, None, 2, 1, 1, 1,'Sample01', 'Name', 'Value','Extra')

xlChart.Location(3, "Sheet1")
xlChartObj = xlSheet.ChartObjects(1)

xlChartObjEmb = xlChartObj.Chart
xlPlotArea = xlChartObjEmb.PlotArea
xlPlotArea.Left, xlPlotArea.Top = 30,10
xlPlotArea.Width, xlPlotArea.Height = 130,130

ここでのポイントは、いったん xlChartObjEmb = xlChartObj.Chart と、 ワンクッション置く必要があるということです (最初、xlChartObj.PlotArea とやって出来なくてハマりました)。 位置とサイズは、Left, Top, Width, Height メソッドで指定します。 ただし、ここで大きな値を指定しても、グラフ部分の枠 (xlChartObj.Width, xlChartObj.Height) に収まる大きさに制限されます(文字はちょっとはみ出してますけど)。 ちなみに、円グラフでは大きさ・位置を指定しないと、小さくてちょっと見づらいです。

サンプルグラフ10

3-5-2: DataLabels

上の円グラフでは、グラフ本体を拡大すると文字も拡大されてます。この文字の大きさを調整してみます。 この「文字」の部分は、円グラフとドーナツグラフでは DataLabels オブジェクトになります。 上のスクリプトの、xlChartObjEmb・・・ の部分からです。

サンプルグラフ11
xlChartObjEmb = xlChartObj.Chart
xlPlotArea = xlChartObjEmb.PlotArea
xlPlotArea.Left, xlPlotArea.Top = 30,30
xlPlotArea.Width, xlPlotArea.Height = 130,130
xlChartObjEmb.SeriesCollection(1).DataLabels().Font.Size = 9

最後の行のようにすることで、文字部分のフォントサイズの変更ができます。 SeriesCollection(1) の1は、系列が1個だけなのでこうなります。 ドーナツグラフのように系列が複数ある場合は、系列ごとに1,2・・などを指定します。

とりあえずここまでです。 他にも、色の変更や3Dグラフの視点の角度とかの設定やらいろいろありますが、 凝り出すときりがありません。 ある程度見やすいグラフを作るための知識としては、これくらいでいいんじゃないでしょうか。


Tanoue Top Page

tanoue@hlj.com