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

Python

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

環境: Windows 10、Python 3.x

背景

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

HTML でのグラフの表示は、JavaScript などのツールがよく知られています。しかしながら、ローカル PC で HTML を表示しようとすると、セキュリティが強化されていることもあり、最近のブラウザではうまく動かず、煩わしいことがあります。

そこで、JavaScript を使わず、Python から html, css のみを使ってグラフを出力するサンプルについてまとめておきます。
フォーマットだけ先に作っておき、データを差し替えることで、HTML のグラフの生成が自由にできるようになります。

設定方法

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

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

③ コマンドプロンプト(または、Anaconda Prompt)を起動し、②のスクリプトを実行してください。
→ ①のフォルダ内に棒グラフのチャート chart1.html が生成されます。この HTML ファイルをダブルクリックすると、ブラウザで表示できます。
④ ③でグラフが表示されたら、Python のサンプルコードのデータを差し替えて活用してください。

サンプルコードを修正する方法は、例えば、以下の通りです。
修正方法
・ スクリプトの末尾あたりで、リスト a1 はデータのタイトル部分になっています。
文字列を変更すると、X軸の各項目の文字列を変更できます。
・ リスト a2 はデータの中身になっています。数値を変更すると棒グラフの高さを変更できます。
・ グラフのタイトル、横軸のタイトル、縦軸のタイトルは、それぞれ、スクリプトの末尾で “title”、”x1”, “y1” としているところです。修正してみてください。
・ また、グラフの縦軸の範囲は y1_max = 100 で設定しています。表示範囲を修正してみてください。
・ なお、データの修正・保存後、Python のスクリプトを再度実行してHTML を再表示すると、グラフが更新されます。
・ リスト(a1, a2)の項目数は、変更するとある程度は自動調整するようにしています。デザインの好み等に応じて、グラフの幅、色、データの項目数を修正してください。

まとめ

Python でグラフを HTML ファイルで出力するサンプルについてまとめました。
データが軽い HTML のグラフで出力できるようになりました。

なお、Python でグラフ表示といえば matplotlib が知られています。
matplotlib を使うサンプルコードについて、以下の関連リンクにまとめています。もし関心がありましたら参考にしてみてください。

関連リンク
・ ドーナツチャートを HTML で表示する 【Python】
・ ポジショニングマップを HTML で表示する 【Python】
・ HTML カレンダーを出力する 【Python】
・ Python で HTML ファイルを出力する
・ 【Python】 グラフを表示する方法 サンプルコード 【matplotlib】

サンプルコード

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をコピーしました