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

Python

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

環境: Windows 11、Python 3.x

背景

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

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

そこで、JavaScript などの特殊なツールは使わずに、Python から html, css のみを使ったグラフを出力するサンプルをまとめておきます。
Python で設定しているデータの部分を差し替えることで、純粋な 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 のグラフが自由に出力できるようになりました。ライブラリ不要で、HTML のサイズも軽くすることが可能です。

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

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

サンプルコード

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