ChatGPTと会話しながらPythonでデータを可視化するアプリケーションを作成してみたのでメモメモ

どうもこんにちは。

Pythonチャレンジ第２弾です。第1弾で環境構築をしていますので、先にそちらを参照してみてください。

↓第1弾はこちら↓

https://qiita.com/PDC-Kurashinak/private/355fcd920aa6803e59f3

第１弾でPython実行環境構築したから何か簡単なアプリ作ってみようと思って作ってみました。

今回は、「CSVデータをグラフで可視化するアプリケーションを作ってみた」って感じです。

# 概要

要件としては以下のような感じです。

1. CSVデータを分析したい
1. 分析結果を可視化したい

上記要件をPythonで実現してみました。

# 構築方法

## 1. 必要なライブラリを追加

以下のコードを`requirements.txt`に記述します。（ライブラリについては最後に説明をしておくこととします。）

```makefile
Flask==2.0.1
pandas==1.3.3
matplotlib==3.4.3
```

## 2. Flaskアプリケーションの作成

python_testディレクトリに`app.py`という名前のファイルを作成し、以下の内容を記述します。

```python
from flask import Flask, render_template
import pandas as pd
import matplotlib.pyplot as plt
import io
import base64

app = Flask(__name__)

@app.route('/')
def index():
    # サンプルデータの読み込み
    df = pd.read_csv('sample_data.csv')

    # データの可視化
    plt.hist(df['some_column'])
    
    # プロットを画像として保存
    img = io.BytesIO()
    plt.savefig(img, format='png')
    img.seek(0)
    
    # 画像をBase64でエンコード
    plot_url = base64.b64encode(img.getvalue()).decode()
    
    return render_template('index.html', plot_url=plot_url)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
```

## 3. HTMLテンプレートの作成

python_testディレクトリに`templates`というディレクトリを作成し、その中に`index.html`という名前のファイルを作成します。

```html
<!DOCTYPE html>
<html>
<head>
    <title>Data Visualization</title>
</head>
<body>
    <h1>Data Visualization Example</h1>
    <img src="data:image/png;base64,{{ plot_url }}" alt="plot">
</body>
</html>
```

## 4. Dockerfileの更新

Dockerfileを以下のコードに書き換えます。

```Dockerfile
# Pythonの公式イメージをベースにする
FROM python:3.9-slim

# 作業ディレクトリを設定
WORKDIR /app

# 必要なファイルをコピー
COPY requirements.txt .
COPY app.py .
COPY templates templates/

# 依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt
```

## 5. docker-compose.ymlの更新

docker-compose.ymlを以下のコードに書き換えます。

```yml
version: '3'

services:
  python-service:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/app
    ports:
      - "5000:5000"
    command: python app.py
```

## 6. CSVファイルの作成

python_testディレクトリに`sample_data.csv`というファイルを作成して、以下の内容を書き込みます。

```csv
id,some_column
1,100
2,150
3,200
4,250
5,300
6,400
7,100
8,200
9,200
```

## 7. コンテナのビルドと起動

ターミナルで`docker-compose up --build`を実行します。

# 結果

上記手順で完了だと思いきや、エラーが起きました。（おそらくMacbookの方限定。。。）

```
Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:5000 -> 0.0.0.0:0: listen tcp 0.0.0.0:5000: bind: address already in use
```

すでにポート5000が使用されているとのエラーが出ました。

「なぬ!?」となったのでネットで調べてみたところ、MacのControlCenterが使用しているっぽいですね。。。

https://tektektech.com/mac-local-5000-port-already-in-use/

# 対処法

`app.py`と`docker-compose.yml`の5000を指定している箇所を5001に変更します。

これで再度、ターミナルで`docker-compose up --build`を実行します。

これで`http://localhost:5001/`にアクセスすると、以下のような画面が表示されます。

![スクリーンショット 2023-09-16 16.56.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/37317ad5-e79c-d076-79e2-c083b737ef49.png)

# ちょいめも

CSVデータに変更を加えて、ページを更新すると変更が反映されます。

# 使用したライブラリについて

## Flask

Flaskは、PythonでWebアプリケーションを作成するための軽量なフレームワークです。

## pandas

pandasは、Pythonでデータ分析を行うためのライブラリです。
大量のデータを効率的に扱ったり、データの加工や分析を行うことができます。
`pd.read_csv('sample_data.csv')`のようにして、CSVファイルを読み込み、データフレームとして操作できます。

## matplotlib

matplotlibは、Pythonでグラフやチャートを描画するためのライブラリです。
データの可視化を行いたいときに使用します。例えば、データの分布をヒストグラムで表示することができます。
`plt.hist(df['some_column'])`のようにして、データのヒストグラムを描画しています。

## io

ioモジュールは、ストリームベースの入出力操作をサポートするためのツールを提供します。
メモリ上に仮想的なファイルを作成して、その中にデータを書き込んだり読み込んだりすることができます。
`img = io.BytesIO()`のようにして、バイトデータを扱うための仮想的なファイルをメモリ上に作成しています。

## base64

base64モジュールは、バイナリデータをASCII文字列にエンコード・デコードするためのツールを提供します。
画像データなどのバイナリデータを、Webページ上で直接表示するための文字列に変換するときなどに使用します。
`plot_url = base64.b64encode(img.getvalue()).decode()`のようにして、バイナリデータをbase64エンコードして文字列に変換しています。

# まとめ

時間換算で30分未満で環境構築からデータ分析＆可視化まで実現することができました。

次はどんな機能を実装してみようか考えるのが楽しくなってきました。

以上


# ソースコードはこちら

https://github.com/pdc-kurashina/python_sample_qiita_01