ベン図を HTML で出力する 【Python】

Python

ベン図を HTML ファイル形式で出力する Python スクリプトについてまとめておきます。csv ファイルに座標データなどを書き出しておくと、読み込んで html 形式で出力します。
以下の環境で動作確認をしています。
環境: Windows 10、Microsoft Edge、Python 3.X

背景

技術やマーケティングの検討をしていると、時々、混沌とした実態をベン図でまとめたくなることがあります。
いわゆる「集合の図」です。

その都度、パワーポイントや Excel で作図をするのも煩雑ですし、流用性が高くありません。
そこで、CSV ファイルにテキストで円の座標などを書き出しておくと、HTML 形式のベン図を出力する Python スクリプトについて、まとめました。
Python とブラウザさえあれば、図の表示が可能です。また、HTML 形式としていますので、サイト上などでの図形の流用も容易となります。
つまり、jpg や png などの画像データを介在させずに作図ができ、データ容量を増やすことなくコピー&ペースト、編集ができるようになります。

設定方法

① PC にフォルダを作成してください。
例: c:\user
② ①で作成したフォルダ内に venn_diagram1.py 等の名前でテキストファイルを作成し、下記のサンプルコードを貼りつけて保存してください。
③ さらに、①のフォルダ内に venn1.csv の名前でテキストファイルを作成し、下記のデータを貼りつけて保存してください。

使い方

④ コマンドプロンプトを起動し、②の Python スクリプトを実行してください。
例: python c:\user\venn_diagram1.py + [enter]
→ ①のフォルダ内に venn1.html という名前でファイルが生成されます。
⑤ 出力された HTML ファイルをダブルクリックして起動し、ブラウザで表示させてみてください。

うまく動いたら

うまく動いたら、csv ファイルのデータを変えてアレンジをしてみてください。
文字列を入れ替えると、オーソドックスなベン図を生成できます。
1つめの事例では円を3つ表示していますが、最後の1行を削除すると2つの円になります。
数字を調整すると、円の位置や大きさ、色などを調整できます。

また、csv ファイルのデータを2つ挙げていますので、差し替えてみてください。

csv ファイルは、各行が1つの円に対応しています。
各行では、以下の順で、カンマ区切りでデータを並べています。
円の X 座標、Y 座標、半径、文字サイズ、文字の位置を微調整するための X 座標、Y 座標(オフセット)、円の色、文字列

対応する数値や文字列を修正してみてください。
また、半径を0にすると文字だけが残ります。任意の位置に文字を表示することができます。

まとめ

Python から、ベン図を出力する方法についてまとめました。
テキストを差し替えて、位置調整をすれば、活用も容易だと思います。

他にも、Python から、画像や HTML のグラフなどを出力する方法について関連リンク等にまとめています。
もしも関心がありましたら、参考にしてみてください。

関連リンク
・ Python で HTML ファイルを出力する
・ HTML のグラフを出力する 【Python】
・ HTML で図形を出力する 【Python】

csv ファイル用のデータ(venn1.csv の名前で保存してください)

データ1

300, 130, 120, 40, 0, 0, #ff0000, A
220, 270, 120, 40, 0, 0, #00ff00, B
380, 270, 120, 40, 0, 0, #0000ff, C

データ2

370, 260, 100, 15,  20,    0, #ffcccc, Big Data 
190, 200, 160, 15,  10,  -90, #aaffaa, Artificial Intelligence
210, 240, 110, 15,   0,  -50, #aaaaff, Machine Learning 
225, 270,  70, 15,  -5,    0, #0000ff, Deep Learning 

サンプルコード

import os 
import unicodedata as ud1 

def read1( file1 ): 
    with open( file1, 'r', encoding='utf-8' ) as f1: 
        str1 = f1.read()
    return str1 

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

def get_a1( str1 ): 
    a1 = read1( file1 ).strip().split( "\n" ) 
    for i1 in range( len( a1 ) ): 
        a1[i1] = a1[i1].split( "," ) 
    return a1 

def strlen1( str1 ): 
    n1 = 0 
    for c1 in str1: 
        if ud1.east_asian_width( c1 ) in 'FWA': 
            n1 = n1 + 2 
        else: 
            n1 = n1 + 1 
    return n1 

def generate_circle_text0(x0, y0, r0, f0, x0_off, y0_off, color0, str0 ): 
    str2 = ''' 
    <circle cx="{x1}" cy="{y1}" r="{r1}" stroke="black" stroke-width="1" fill="{color1}" fill-opacity="0.3" />
'''.format( x1=x0, y1=y0, r1=r0, color1=color0 ) 
    x3=int( x0 - f0 *( (strlen1(str0)-1)*0.25 + 0.22 ) + x0_off ) 
    y3=int( y0 + f0 * 0.32 + y0_off )  
    str3 = ''' 
    <text x="{x2}" y="{y2}" font-family="meiryo" font-size="{f1}" >{str1}</text>
'''.format( x2=x3, y2=y3, f1=f0, str1=str0 ) 
    if r0 > 0: 
        str2 = str2 + str3 
    else: 
        str2 = str3 
    return str2 

def generate_html0( str0 ): 
    str1 = ''' 
<html lang="ja">
<body>
  <svg width="600" height="400" viewBox="0 0 600 400" style="background:#fbfbfb" >
{str2} 
  </svg>
</body> 
</html> 
'''.format( str2 = str0 ) 
    return str1 

def generate_html1( a1 ): 
    str1 = "" 
    for i1 in range( len( a1 ) ): 
        x1     = int( a1[i1][0] )           # x1 
        y1     = int( a1[i1][1] )           # y1 
        r1     = int( a1[i1][2] )           # radius 
        f1     = int( a1[i1][3] )           # font size 
        x1_off = int( a1[i1][4] )           # font offset x 
        y1_off = int( a1[i1][5] )           # font offset y 
        color1 = str( a1[i1][6] ).strip()   # chart color 
        str2   = str( a1[i1][7] ).strip()   # characters 
        str2 = generate_circle_text0(x1, y1, r1, f1, x1_off, y1_off, color1, str2) 
        str1 = str1 + str2 + "\n" 
    str1 = generate_html0( str1 )  
    return str1 

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

a1 = get_a1( file1 ) 
print( a1 ) 

str1 = generate_html1( a1 ) 

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

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