PythonでSVG図解を作成する方法

## はじめに
SVG（Scalable Vector Graphics）は、ベクターグラフィックスを描画するためのXMLベースの形式です。Pythonを使用してSVGを生成することで、プログラマティックに図解やダイアグラムを作成することができます。この記事では、Pythonを使ってSVGを作成する方法について、基本から実践的な例まで説明します。

Claudeを使って図解をSVG形式で作成してもらっていたので、プログラムで同様の作業ができるか確認してみました。図解をもっと効率的に作成できる方法を模索したいという動機もあり、この記事を書いています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/82b75701-e2cb-fa0d-4da4-24d38f85c486.png)


## 目次
1. SVGの基本概念
2. PythonでSVGを生成する基本的な方法
3. svgwriteライブラリの使用方法
4. 実践的な図解作成例
5. まとめ

## 1. SVGの基本概念
SVGは以下のような特徴を持っています：
- XMLベースのベクター形式
- 拡大縮小しても品質が劣化しない
- テキストエディタで編集可能
- Web上での表示に適している

## 2. PythonでSVGを生成する基本的な方法

### 2.1 シンプルな方法（文字列操作）
最も基本的な方法は、文字列として直接SVGを生成することです。

```python
def create_simple_svg():
    svg = f'''<?xml version="1.0" encoding="UTF-8"?>
    <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
        <rect x="10" y="10" width="80" height="80" fill="blue" />
    </svg>'''
    
    with open('output.svg', 'w') as f:
        f.write(svg)

create_simple_svg()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/060a1615-3e11-d082-2643-cccd4a956687.png)


## 3. svgwriteライブラリの使用方法

svgwriteは、PythonでSVGを作成するための便利なライブラリです。

### 3.1 インストール
```bash
pip install svgwrite
```

### 3.2 基本的な使い方

```python
import svgwrite

def create_svg_with_svgwrite():
    dwg = svgwrite.Drawing('output.svg', size=('100px', '100px'))
    
    # 四角形を描画
    dwg.add(dwg.rect(insert=(10, 10), size=(80, 80), fill='blue'))
    
    # 円を描画
    dwg.add(dwg.circle(center=(50, 50), r=30, fill='red'))
    
    dwg.save()

create_svg_with_svgwrite()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/eb6e0038-5580-5268-207f-0c77adc9774a.png)

## 4. 実践的な図解作成例

### 4.1 フローチャートの作成

```python
import svgwrite

def create_flowchart():
    # 描画領域の作成
    dwg = svgwrite.Drawing('flowchart.svg', size=('400px', '300px'))
    
    # スタイル定義
    styles = {
        'box': {
            'fill': 'white',
            'stroke': 'black',
            'stroke-width': 2
        },
        'arrow': {
            'stroke': 'black',
            'stroke-width': 2,
            'fill': 'none',
            'marker-end': 'url(#arrow)'
        }
    }
    
    # 矢印マーカーの定義
    marker = dwg.marker(insert=(10, 6), size=(10, 10), orient='auto')
    marker.add(dwg.path(d='M0,0 L10,6 L0,12 L4,6 Z', fill='black'))
    dwg.defs.add(marker)
    
    # ボックスの追加
    box1 = dwg.rect(insert=(50, 50), size=(100, 50), **styles['box'])
    box2 = dwg.rect(insert=(50, 150), size=(100, 50), **styles['box'])
    
    # テキストの追加
    text1 = dwg.text('開始', insert=(75, 80))
    text2 = dwg.text('処理', insert=(75, 180))
    
    # 矢印の追加
    arrow = dwg.path(d='M100,100 L100,150', **styles['arrow'])
    
    # 要素の追加
    dwg.add(box1)
    dwg.add(box2)
    dwg.add(text1)
    dwg.add(text2)
    dwg.add(arrow)
    
    dwg.save()

create_flowchart()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/8790bbec-223d-86ac-d443-77bed09f4be7.png)


### 4.2 組織図の作成

```python
import svgwrite

def create_org_chart():
    dwg = svgwrite.Drawing('org_chart.svg', size=('500px', '400px'))
    
    # ボックススタイル
    box_style = {
        'fill': '#E6E6FA',
        'stroke': '#4B0082',
        'stroke-width': 2,
        'rx': 5,
        'ry': 5
    }
    
    # 線のスタイル
    line_style = {
        'stroke': '#4B0082',
        'stroke-width': 2
    }
    
    # ボックスの作成
    boxes = [
        {'text': '社長', 'x': 200, 'y': 50},
        {'text': '営業部長', 'x': 100, 'y': 150},
        {'text': '技術部長', 'x': 300, 'y': 150},
    ]
    
    # ボックスとテキストの描画
    for box in boxes:
        dwg.add(dwg.rect(insert=(box['x'], box['y']),
                        size=(100, 40),
                        **box_style))
        dwg.add(dwg.text(box['text'],
                        insert=(box['x'] + 20, box['y'] + 25),
                        fill='#4B0082'))
    
    # 線の描画
    dwg.add(dwg.line((250, 90), (250, 120), **line_style))
    dwg.add(dwg.line((250, 120), (150, 120), **line_style))
    dwg.add(dwg.line((250, 120), (350, 120), **line_style))
    dwg.add(dwg.line((150, 120), (150, 150), **line_style))
    dwg.add(dwg.line((350, 120), (350, 150), **line_style))
    
    dwg.save()

create_org_chart()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e5335ba4-db3b-c2b6-8ded-2ebf6f40e202.png)

## 5. まとめ

Pythonを使用してSVG図解を作成する方法について説明しました。主なポイントは以下の通りです：

- 文字列操作による基本的なSVG生成
- svgwriteライブラリを使用した効率的な図解作成
- 実践的なフローチャートや組織図の作成例

### メリット
- プログラマティックに図解を生成できる
- データに基づいた動的な図解の作成が可能
- バージョン管理がしやすい
- 再利用性が高い

### 注意点
- SVGの基本的な理解が必要
- 複雑な図解の場合、コードが長くなる可能性がある
- デザイン面での細かい調整が必要な場合がある

## 参考文献
- [svgwrite公式ドキュメント](https://svgwrite.readthedocs.io/)
- [MDN SVGリファレンス](https://developer.mozilla.org/ja/docs/Web/SVG)

## 感想
ChatGPTで図解のPythonコードを生成してもらい、それを手動で編集するという方法も考えられます。また、よく使うテンプレートをプログラムで自動化し、必要な部分だけを簡単に書き換えられるようにするのも便利そうです。

たとえば、勉強会や定例会のスライド作成の元ネタを準備する際にも活用できるかもしれません。