「Arduinoで取ったセンサーのデータ、CSVに保存したはいいけど…どうやってグラフにすればいいの?」
こんな悩みを持ったことはありませんか?電子工作やIoTプロジェクトを進めていると、センサーからデータを取得できるようになった次のステップとして、「データを見える形にしたい」という気持ちが出てきますよね。
そこで今回は、Pythonの定番グラフライブラリ matplotlib を使って、センサーログデータをきれいにグラフ化する方法を丁寧に解説していきます。Arduinoやラズパイで取得したCSVデータを読み込んで、折れ線グラフ・複数センサーの比較グラフ・リアルタイム風グラフまで、ステップごとにサンプルコードつきで紹介します 📊
「むずかしそう」が「できそう」に変わる記事を目指していますので、ぜひ最後まで読んでみてください!
この記事の対象読者と難易度

- ✅ 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コースや電子部品もまとめています。





