HTML の棒グラフを出力する 【Python】

Python

Python で、棒グラフを HTML ファイルで生成するサンプルコードについてまとめておきます。
JavaScript などのライブラリは使わず、ローカルでも動作する Webグラフを生成することにします。Python から HTML でのグラフ表示が可能になります。
以下の環境で動作確認をしています。

環境: Windows パソコン、Python 3.x

背景

Python でプログラミングをしていると、数値をグラフにして HTML 形式で出力したくなることがあります。

HTML でのグラフの表示は、JavaScript などのライブラリがよく知られています。
しかしながら、ライブラリの設定が煩雑ですし、ライブラリの使い方を覚えないと使いこなせない、ネットに接続できないと動かない(ローカルでは動かない)など、後から制約事項が判明することがけっこうあり、煩わしいことがあります。

そこで、JavaScript などの特殊なライブラリは使わずに、Python から直接 HTML 形式で書かれたグラフを出力するスクリプトについてまとめておくことにします。
平易な HTML を出力するだけですので、Windows や Mac、Linux、スマートフォンなど、デバイスの制約がほとんどなく参照できることになります。
また、スクリプトの数値データの部分をカスタマイズすることで、HTML のグラフを自由に作成できるようになります。

設定方法

① パソコン内にフォルダを作成してください。
例: C:/user
② ①のフォルダに html_bar_chart1.py の名前でテキストを作成し、下記のサンプルコードを貼りつけて保存してください。
例: C:/user/html_bar_chart1.py

使い方: Python から HTML のグラフを出力する

③ コマンドプロンプト(または、Anaconda Prompt)を起動し、②のスクリプトを実行してください。
例: python C:user/html_bar_chart1.py

→ ①のフォルダ内に棒グラフのチャート chart1.html が生成されたら成功です!
HTML ファイルをダブルクリックすると、ブラウザで表示できます。

うまく動いたら

うまく動いたら、スクリプトの数値データや文字列の部分を書き換えて反映されることを確認してみてください。スクリプトの末尾部分で、数値や文字列を定義しています。
また、出力された HTML の内容を確認し、対応する Python のスクリプトを変更することで、より洗練したデザインに修正してみてください。
スクリプトを修正した場合は、保存後に上記の③を再度実行してブラウザで再表示させることで、表示を更新できます。

サンプルスクリプトの説明

・ スクリプトの前半の generate_html_head1 関数で、<head>…</head> 部分の文字列を定義しています。
・ generate_html_body1 関数で、<body>…</body> 部分を定義しています。
・ generate_html1 関数で、上記の2つの関数を呼び出して、全体の HTML ファイルの文字列を生成する処理を定義しています。
・ Python を実行すると、path1 = … 以降の処理が順次、実行されます。
グラフに用いるリスト a1 と a2 を定義し、上記の generate_html1 関数を呼び出すことで、HTML の文字列を生成し、保存します。
・ リスト a1 の部分では、データのタイトル部分を定義しています。
文字列を変更することで、X軸の各項目の文字列を変更できます。
・ リスト a2 は、棒グラフの数値を定義しています。
数値を変更することで、棒グラフの高さを設定できます。
・ グラフのタイトル、横軸のタイトル、縦軸のタイトルは、それぞれ、”title”、”x1″, “y1” で定義しています。
・ また、グラフの縦軸の範囲は y1_max = 100 で設定しています。表示範囲を修正してみてください。
・ リスト (“a1”, “a2″)の項目数などは、変更するとある程度は自動調整するようにしています。
好みに応じて、データの項目数、グラフの領域、色、フォントなどを自由にカスタマイズしてください。

まとめ

Python で棒グラフを HTML ファイルで出力するサンプルについてまとめました。
シンプルな HTML のグラフが自由に出力できるようになりました。ライブラリ不要で、HTML のサイズも軽くすることが可能です。

なお今回は、スクリプトにデータを埋め込んで、棒グラフを出力するスクリプトについてまとめました。応用編として、テキストファイルを読み込んで折れ線グラフを出力するスクリプトなどについてもまとめています。
もし、関心があるようでしたら、以下の関連リンクも参考にしてみてください。

関連リンク
・ HTML の折れ線グラフを出力する 【Python】
・ HTML のカレンダーを出力する 【Python】
・ Python で HTML ファイルを出力する
・ グラフを表示する 【matplotlib & Python】
・ 標準的な座標平面とグラフを描画する 【Python】
・ ドーナツチャートを HTML で表示する 【Python】
・ ポジショニングマップを HTML で表示する 【Python】

サンプルコード html_bar_chart1.py

import os 

def write1( file1, str1 ): 
    with open( file1, 'w', encoding='utf-8' ) as f1: 
        f1.write( str1 ) 
    return 0 

def generate_html_head1(): 
    str1 = ''' 
<html lang="ja">
<head>
<style type="text/css">
.container1 { 
  height: 400px; 
  width: 700px; 
  display: flex;
  flex-direction: column; 
  align-items:stretch;
  flex-wrap:wrap;
  background-color: #FAFAFA;
} 
.chart1 { 
  height: 250px; 
  width: 550px;
  margin-left: 50px; 
  margin-right: 10px; 
  margin-top: 10px; 
  margin-bottom: 40px; 
  border: 1px gray solid; 
  display: flex; 
  flex-direction: row; 
  align-items:flex-end;
  flex-wrap:wrap;
  background-color: #FFFFFF;
} 
.space1 { 
  background-color: #FFFFFF;
  margin-left:10px;
  margin-right:10px;
} 
.bar1 { 
  box-sizing: border-box;
  background-color: #C0E0F0;
  margin-left:10px;
  margin-right:10px;
} 
.y_and_chart1 { 
  display: flex; 
  flex-direction: row; 
} 
.word1 { 
  text-align:center; 
  margin-top: 10px; 
  margin-bottom: 10px; 
} 
.word2 { 
  transform-origin: right top; 
  transform: rotate( -90deg ); 
  text-align:left; 
  margin-right: 0px; 
  margin-left: 0px; 
  margin-top: 120px; 
  margin-bottom: 0px; 
} 
.word3 { 
  text-align:center; 
  margin-top: 10px; 
  margin-bottom: 10px; 
  font-size: 12px; 
} 
.word4 { 
  text-align:center; 
  margin-top: 10px; 
  margin-bottom: 10px; 
} 
</style>
</head>
''' 
    return str1 

def generate_html_body1( title0, x0_axis, y0_axis, y0_max, a1, a2 ): 
    str2_body1 = '''
<body>
  <div class="container1">
    <div class="word1">{title1}</div>
    <div class="y_and_chart1">
      <div class="word2">{y1_axis}</div> 
      <div class="chart1">
'''.format( title1 = title0, y1_axis = y0_axis ) 

    bar_width1 = str( int( 550/len( a1 ) - 10*2 ) ) 
    str2_body2 = "" 
    for i1 in range( len( a1 ) ): 
        y1 = int( a2[i1]/y0_max*100 )
        str3 = '        <div>' 
        str3 = str3 + '<div class="space1" style="height: ' + str( 100-y1 ) + '%; width: ' + bar_width1 + 'px "></div>' 
        str3 = str3 + '<div class="bar1" style="height: ' + str( y1 ) + '%; width: ' + bar_width1 + 'px ">' 
        str3 = str3 + '</div><div class="word3">' + str( a1[i1] ) + '</div></div>\n' 
        str2_body2 = str2_body2 + str3 
    str2_body2 = str2_body2 + '      </div>' 
    str2_body3 = '''
    </div> 
    <div class="word4">{x1_axis}</div>
  </div> 
</body>
</html>
'''.format( x1_axis = x0_axis ) 
    return str2_body1 + str2_body2 + str2_body3 

def generate_html1( title0, x1_axis, y1_axis, y1_max, a1, a2 ): 
    str1 = generate_html_head1() 
    str2 = generate_html_body1( title0, x1_axis, y1_axis, y1_max, a1, a2 ) 
    return str1 + str2 

path1 = os.path.dirname(__file__) + "/" 

a1 = [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"] 

a2 = [ 10, 20, 30, 40, 50, 60, 65, 70, 75, 80, 85, 90] 

y1_max = 100 
str1 = generate_html1( "title", "x1", "y1", y1_max, a1, a2 ) 

print( str1 ) 

file1 = path1 + "chart1.html" 
write1( file1, str1 ) 


タイトルとURLをコピーしました