IoT・電子工作

Pythonで電子工作データを可視化!matplotlibでセンサーログをグラフ化する方法

「Arduinoで取ったセンサーのデータ、CSVに保存したはいいけど…どうやってグラフにすればいいの?」

こんな悩みを持ったことはありませんか?電子工作やIoTプロジェクトを進めていると、センサーからデータを取得できるようになった次のステップとして、「データを見える形にしたい」という気持ちが出てきますよね。

そこで今回は、Pythonの定番グラフライブラリ matplotlib を使って、センサーログデータをきれいにグラフ化する方法を丁寧に解説していきます。Arduinoやラズパイで取得したCSVデータを読み込んで、折れ線グラフ・複数センサーの比較グラフ・リアルタイム風グラフまで、ステップごとにサンプルコードつきで紹介します 📊

「むずかしそう」が「できそう」に変わる記事を目指していますので、ぜひ最後まで読んでみてください!

この記事の対象読者と難易度

data visualization graph
data visualization graph / Photo by Lukas Blazek via Pexels
  • ✅ PythonでCSVファイルを読んだことがある方
  • ✅ ArduinoやラズパイなどでセンサーデータをCSV保存したことがある方
  • ✅ matplotlibを使ったことがない、またはほぼ初めての方
  • ✅ データ可視化に興味がある電子工作ユーザー

難易度:⭐⭐☆☆☆(初〜中級者向け)

matplotlibって何?ざっくり説明

matplotlib(マットプロットリブ) は、Pythonでグラフや図を描画するためのライブラリです。イメージとしては「Pythonで動くExcelグラフ作成ツール」のような存在です。

折れ線グラフ・棒グラフ・散布図・ヒストグラムなど、ほぼあらゆる種類のグラフを数行のコードで作れます。データ分析・機械学習・電子工作の可視化など、幅広い分野で使われている定番ライブラリですよ。

まずはインストールから確認しておきましょう。

# matplotlibのインストール(未インストールの場合)
pip install matplotlib

# pandasも合わせてインストールしておくと便利です
pip install pandas

インストールが完了したら、早速コードを書いていきましょう!

STEP 1:センサーログCSVを用意する

今回は、Arduinoや温湿度センサーから取得したデータを想定したCSVファイルを使います。まずはサンプルのCSVを用意しましょう。

📁 sensor_log.csv(このような形式を想定しています)

timestamp,temperature,humidity
2024-01-01 09:00:00,22.3,55.1
2024-01-01 09:01:00,22.5,54.8
2024-01-01 09:02:00,22.8,54.5
2024-01-01 09:03:00,23.1,54.0
2024-01-01 09:04:00,23.4,53.7
2024-01-01 09:05:00,23.6,53.5
2024-01-01 09:06:00,23.3,53.8
2024-01-01 09:07:00,23.0,54.2
2024-01-01 09:08:00,22.7,54.6
2024-01-01 09:09:00,22.4,55.0

実際のArduinoスケッチでは、Serial.println() でこのような形式のデータをシリアル出力し、Pythonスクリプトやターミナルでファイルに書き出す方法がよく使われます。今回はこのCSVファイルがすでにある前提で進めていきますね。

STEP 2:CSVを読み込んで基本的な折れ線グラフを描く

まずは一番シンプルな例から。温度データを折れ線グラフで表示してみましょう。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# CSVファイルを読み込む
df = pd.read_csv('sensor_log.csv')

# timestamp列をdatetime型に変換(グラフの横軸に使うため)
df['timestamp'] = pd.to_datetime(df['timestamp'])

# グラフを描画する
plt.figure(figsize=(10, 4))  # グラフのサイズ指定(横10インチ、縦4インチ)

plt.plot(
    df['timestamp'],       # 横軸:時刻
    df['temperature'],     # 縦軸:温度
    color='tomato',        # 線の色
    linewidth=2,           # 線の太さ
    marker='o',            # データ点にマーカーを表示
    label='温度 (°C)'      # 凡例のラベル
)

# 軸ラベルとタイトルを設定
plt.xlabel('時刻')
plt.ylabel('温度 (°C)')
plt.title('センサーログ:温度の変化')

# 横軸の時刻フォーマットを設定
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
plt.gcf().autofmt_xdate()  # 横軸ラベルを斜めにして見やすくする

plt.legend()   # 凡例を表示
plt.grid(True) # グリッド線を表示
plt.tight_layout()  # レイアウトを自動調整
plt.show()

ポイントをまとめるとこんな感じです👇

  • pd.to_datetime() でtimestamp列を日時型に変換しないと、横軸が正しく表示されません
  • figsize=(10, 4) でグラフのサイズをインチ単位で指定できます
  • marker=’o’ を指定すると、各データ点に丸いマーカーが付いて見やすくなります
  • plt.grid(True) でグリッド線を入れると、値の読み取りがグッと楽になります

STEP 3:複数センサーのデータを1つのグラフに重ねる

温度と湿度、2つのデータを1つのグラフに重ねて表示したいケース、ありますよね。ただし、単位が違う(°Cと%)ので、第2軸(右側のY軸) を使うのがスマートです。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

df = pd.read_csv('sensor_log.csv')
df['timestamp'] = pd.to_datetime(df['timestamp'])

# 第1軸(左)と第2軸(右)を両方持つグラフを作成
fig, ax1 = plt.subplots(figsize=(10, 5))

# --- 温度:左のY軸に描画 ---
color_temp = 'tomato'
ax1.set_xlabel('時刻')
ax1.set_ylabel('温度 (°C)', color=color_temp)
ax1.plot(df['timestamp'], df['temperature'],
         color=color_temp, linewidth=2, marker='o', label='温度')
ax1.tick_params(axis='y', labelcolor=color_temp)

# --- 湿度:右のY軸に描画 ---
ax2 = ax1.twinx()  # 右側に第2のY軸を作成
color_hum = 'steelblue'
ax2.set_ylabel('湿度 (%)', color=color_hum)
ax2.plot(df['timestamp'], df['humidity'],
         color=color_hum, linewidth=2, marker='s', linestyle='--', label='湿度')
ax2.tick_params(axis='y', labelcolor=color_hum)

# 横軸の時刻フォーマット
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
fig.autofmt_xdate()

# 凡例を両軸から取得してまとめて表示
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')

plt.title('センサーログ:温度と湿度の変化')
fig.tight_layout()
plt.show()

ここが重要です ✅

  • ax1.twinx() を使うと、同じ横軸を共有しながら右側にY軸を追加できます
  • 単位が違うデータを同じY軸に乗せると、スケールがズレてグラフが読みにくくなります。第2軸を使うのがベストプラクティスです
  • 凡例は get_legend_handles_labels() で両方の軸から取得してまとめると、スッキリ表示できます

STEP 4:グラフをファイルに保存する


グラフを毎回手動で確認するのではなく、PNG画像として自動保存 しておくと、ログと一緒に管理できてとても便利です。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime

df = pd.read_csv('sensor_log.csv')
df['timestamp'] = pd.to_datetime(df['timestamp'])

fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(df['timestamp'], df['temperature'],
        color='tomato', linewidth=2, marker='o')
ax.set_xlabel('時刻')
ax.set_ylabel('温度 (°C)')
ax.set_title('センサーログ:温度の変化')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
fig.autofmt_xdate()
ax.grid(True)
fig.tight_layout()

# ファイル名に現在時刻を入れて保存(上書き防止)
now_str = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f'sensor_graph_{now_str}.png'
fig.savefig(filename, dpi=150)  # dpi=150で高解像度に保存
print(f'グラフを保存しました:{filename}')

plt.show() の代わりに fig.savefig() を使うのがポイントです。dpi(解像度)を150〜300 に設定すると、レポートや資料に貼りやすい画質になります 🖼️

STEP 5:異常値を色で目立たせる(応用編)

センサーデータの可視化でよくあるニーズが、「しきい値を超えた部分を赤くハイライトしたい」というものです。温度が25°Cを超えたら警告、みたいなやつですね。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

df = pd.read_csv('sensor_log.csv')
df['timestamp'] = pd.to_datetime(df['timestamp'])

# しきい値の設定
THRESHOLD = 23.0

fig, ax = plt.subplots(figsize=(10, 4))

# 通常範囲と異常範囲でデータを色分け
for i in range(len(df) - 1):
    x_vals = [df['timestamp'].iloc[i], df['timestamp'].iloc[i + 1]]
    y_vals = [df['temperature'].iloc[i], df['temperature'].iloc[i + 1]]
    # しきい値を超えているセグメントを赤に
    color = 'red' if y_vals[0] >= THRESHOLD else 'steelblue'
    ax.plot(x_vals, y_vals, color=color, linewidth=2)

# マーカーも色分けして表示
colors = ['red' if t >= THRESHOLD else 'steelblue'
          for t in df['temperature']]
ax.scatter(df['timestamp'], df['temperature'], c=colors, zorder=5)

# しきい値のラインを表示
ax.axhline(y=THRESHOLD, color='orange', linestyle='--',
           linewidth=1.5, label=f'しきい値 {THRESHOLD}°C')

ax.set_xlabel('時刻')
ax.set_ylabel('温度 (°C)')
ax.set_title('センサーログ:異常値ハイライト付き温度グラフ')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
fig.autofmt_xdate()
ax.legend()
ax.grid(True, alpha=0.4)
fig.tight_layout()
plt.show()

ポイントをまとめるとこんな感じです👇

  • axhline() で水平方向のしきい値ラインを簡単に引けます
  • ループでセグメントごとに色を変えることで、「ここから危険ゾーン」が一目でわかるグラフになります
  • scatter()plot() を組み合わせると、線とマーカーで別々の色設定ができます

STEP 6:複数ファイルをまとめてグラフ化する(実用編)

「毎日ログが1ファイルずつ増えていくんだけど、まとめてグラフにしたい…」という場面、電子工作ロガーあるあるですよね。glob を使えばスッキリ解決できます。

import pandas as pd
import matplotlib.pyplot as plt
import glob
import os

# フォルダ内のCSVファイルを全て取得
csv_files = sorted(glob.glob('./logs/sensor_log_*.csv'))

if not csv_files:
    print('CSVファイルが見つかりませんでした。')
else:
    fig, ax = plt.subplots(figsize=(12, 5))

    for filepath in csv_files:
        df = pd.read_csv(filepath)
        df['timestamp'] = pd.to_datetime(df['timestamp'])

        # ファイル名をラベルに使用
        label = os.path.basename(filepath).replace('.csv', '')
        ax.plot(df['timestamp'], df['temperature'],
                linewidth=1.5, marker='o', markersize=3, label=label)

    ax.set_xlabel('時刻')
    ax.set_ylabel('温度 (°C)')
    ax.set_title('複数日センサーログの温度比較')
    ax.legend(fontsize=8)
    ax.grid(True, alpha=0.4)
    fig.autofmt_xdate()
    fig.tight_layout()
    plt.show()

glob.glob() にパスパターンを渡すだけで、一致するファイルのリストを取得できます。sorted() を組み合わせると日付順に並ぶので、時系列グラフにそのまま使えます 📂

よくあるつまずきポイントと対処法


実際にやってみると、こんなエラーや問題に遭遇することがあります。確認しておきましょう。

🔴 グラフが表示されない

環境によっては plt.show() で何も表示されないことがあります。Jupyter Notebookの場合は先頭に %matplotlib inline を入れてみてください。VSCodeのインタラクティブウィンドウでも同様です。

🔴 横軸の日時が文字化けする・読めない

日本語フォントが設定されていないと、グラフのテキストが豆腐(□)になることがあります。

# 日本語フォントを設定する(Windows・Mac共通で動きやすい設定)
import matplotlib
matplotlib.rcParams['font.family'] = 'IPAexGothic'  # Linuxの場合
# matplotlib.rcParams['font.family'] = 'Meiryo'      # Windowsの場合
# matplotlib.rcParams['font.family'] = 'Hiragino Sans' # Macの場合

OS に合わせてフォントを設定してみてください。japanize-matplotlib というライブラリを使うと設定が一発で済むのでおすすめです(pip install japanize-matplotlib)。

🔴 CSV読み込み時にエラーが出る

Arduinoのシリアル出力をそのままファイルに書いた場合、文字コードが Shift-JIS になっていることがあります。pd.read_csv('file.csv', encoding='shift_jis') のように encoding を指定してみてください。

まとめ

今回は、Pythonの matplotlib を使って電子工作のセンサーログデータをグラフ化する方法を、ステップごとに紹介しました 🎉

ざっくりとした流れをおさらいするとこんな感じです:

  • ✅ STEP 1:センサーログCSVを用意する
  • ✅ STEP 2:pandasで読み込み、基本的な折れ線グラフを描く
  • ✅ STEP 3:第2軸を使って複数センサーを1グラフに重ねる
  • ✅ STEP 4:グラフをPNG画像として保存する
  • ✅ STEP 5:しきい値を超えた部分を色で強調する
  • ✅ STEP 6:複数ファイルをまとめてグラフ化する

matplotlibはシンプルなコードで本格的なグラフが作れる、電子工作との相性バツグンのライブラリです。センサーデータを「眺めるデータ」から「見えるデータ」に変えると、異常の発見や傾向の把握がぐっとしやすくなりますよ。

ぜひ自分のセンサーログを使って試してみてください。うまくグラフが描けたら、次は Webブラウザで見られるインタラクティブグラフ(Plotly) にも挑戦してみると、一気に表現の幅が広がります。一緒に学んでいきましょう!💪

📡 Arduinoをもっと深く学ぼう!

Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。

Arduinoロボット入門のおすすめコース・部品を見る →

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

Arduinoをはじめよう 第4版 (Make: PROJECTS)

もしも

Arduinoをはじめよう 第4版 (Make: PROJECTS)

Arduino公式推薦の定番入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です