理系的な戯れ

理工学系とくにロボットやドローンに関する計算・プログラミング等の話題を扱って、そのようなことに興味がある人たちのお役に立てればと思っております。

研究に役立つグラフの書き方 - データを正しく可視化する

はじめに

「実験データは取れたけど、数値の羅列を見ても何もわからない...」 「グラフを作るのは面倒だから、とりあえず数値表だけでレポートを出そう」

こんな経験はありませんか?

実は、データの可視化は研究において最も重要なスキルの一つです。なぜなら:

  • 数値だけでは見えない傾向が一目でわかる

    • 1000個のデータ点を数値で見ても、上昇傾向なのか周期性があるのかは判断できません
    • グラフにすれば、数秒で全体像が把握できます
  • 異常値や問題点が即座に発見できる

    • センサの故障、測定ミス、ノイズの混入など
    • 数値表では見逃してしまう問題も、グラフなら一目瞭然
  • 仮説の検証が直感的にできる

    • 「このピークは何だろう?」「この周期は理論値と一致するか?」
    • 可視化することで、新たな発見につながることも

しかし、「グラフ作成は面倒」「どうやって作ればいいかわからない」と感じることもあるでしょう。

この記事で学べること

この記事では、どんな環境でもデータを可視化できるように、3つのツールを使い分ける方法を学びます:

  1. Excel - 慣れ親しんだツールですが、実はデータ分析には不向きな面も。正しい使い方と限界を知る

  2. gnuplot - 無料で軽量、どんな環境でも動作。簡単な操作で論文品質のグラフが作成可能

  3. matplotlib - Python環境が必要ですが、柔軟性は最高。研究で必要なあらゆるグラフに対応

なぜ3つのツールを学ぶのか

それぞれのツールには得意・不得意があります:

  • Excel:手軽だが、大量データでは動作が重く、自動化も困難
  • gnuplot:軽量で美しいグラフが作れるが、初めての人には少し敷居が高い
  • matplotlib:最も柔軟だが、プログラミングの知識が必要

状況に応じて使い分けることで、効率的に、そして美しくデータを可視化できるようになります。

この記事の対象読者

  • IMUやセンサのデータを扱っているが、うまく可視化できない方
  • 時系列データを折れ線グラフで描いてしまい、指導教員に指摘された経験がある方
  • データの可視化は面倒だと感じている方
  • 研究発表用の綺麗なグラフを作りたい方

さあ、データに隠された真実を「見える化」する旅を始めましょう!

注意: この記事で使用するサンプルデータの作成方法は、付録に詳しく記載しています。実際に手を動かしながら学びたい方は、まず付録を参照してサンプルデータを用意してください。


1. なぜ時系列データを散布図で描くのか?

「時系列データ=折れ線グラフ」と考えることが多いかもしれませんが、実は学術研究において、散布図の方が適切な場面が多いのです。

これは意外に思われるかもしれませんが、データの性質を正確に表現するという観点から重要なポイントです。

折れ線グラフの根本的な問題

折れ線グラフの最大の問題は、データ点の間に勝手に線を引いてしまうことです。

例えば、IMUから1秒間隔でデータを取得したとします:

  • 0秒: 10 deg/s
  • 1秒: 15 deg/s
  • 2秒: 12 deg/s

折れ線グラフでは、0.5秒の時点で12.5 deg/sだったかのような線が引かれます。でも、0.5秒のデータは存在しません!

これは単なる見た目の問題ではありません:

  • 存在しないデータを作り出している
  • 測定間隔の情報が失われる
  • データの信頼性を損なう

なぜ散布図なのか

散布図の素晴らしさは、測定したデータだけを正直に表示することです。

散布図では:

  • 実際に測定した点だけが表示される
  • 測定間隔が視覚的にわかる
  • データの密度から情報が読み取れる
  • ノイズや異常値が明確に見える

さらに重要なのは、散布図でも折れ線グラフのような見た目は作れるということです。

具体例:同じデータ、異なる表現

時刻[s]  角速度[deg/s]
0        10.2
1        15.1
2        12.3
3        18.5
5        14.2  ← 4秒のデータが欠損
6        16.8

このデータを見てください。4秒のデータが欠損しています。

  • 折れ線グラフ:3秒と5秒の間に線が引かれ、4秒のデータがあるかのように見える
  • 散布図:4秒にデータがないことが一目瞭然

また、一部のツールでは、データの順序だけで折れ線を引いてしまい、実際の時間軸を無視することがあります。

例えば、不等間隔のサンプリング:

  • 0秒、1秒、2秒、5秒、10秒...

このようなデータを折れ線グラフにすると、等間隔に見えてしまうツールがあります。これは科学的に誤った表現です。

学生へのメッセージ:折れ線グラフをやめよう

シンプルです:今日から折れ線グラフを使うのをやめましょう。

「でも、折れ線グラフの方が見やすいのでは?」と思うかもしれません。

実は、散布図でも:

  • 点を小さくすれば、折れ線のように見える
  • 必要なら後から線を追加できる(ただし慎重に)
  • データの本質を損なわない

研究において大切なのは、データを正確に表現することです。見た目の美しさより、科学的な正確さを優先しましょう。

まとめ:散布図を使う理由

  1. 正確性:測定したデータのみを表示
  2. 情報量:サンプリング間隔、欠損、密度がわかる
  3. 柔軟性:必要に応じて表現を調整可能
  4. 学術的妥当性:研究論文の標準

次のセクションでは、実際にExcelで散布図を作る方法を学びましょう。もう二度と折れ線グラフには戻れなくなるはずです!


2. Excel での基本的な散布図作成

Excelは馴染みのあるツールですが、研究用のデータ可視化には向いていません。また、環境によってはExcelが使えない場合もあるため、LibreOffice Calcなどの無料の表計算ソフトの使用も検討してください。ここでは最低限の使い方だけを説明します。

基本的な手順

  1. データの準備

    • A列に時刻、B列にセンサデータを配置
    • CSVファイルをそのまま開ける
  2. 散布図の作成

    • データ範囲を選択
    • 「挿入」→「散布図」を選択
    • 注意: 「折れ線グラフ」ではなく「散布図」!
  3. 最低限の設定

    • 軸ラベルを追加(時刻[s]、角速度[deg/s]など)
    • マーカーサイズを小さく(2-3pt)
    • 不要な線は削除

Excelの限界

  • 大量データで動作が重い(数千点以上で顕著)
  • グラフの再現性がない(手作業のため)
  • 細かい調整が困難
  • バッチ処理ができない

結論:Excelは初期確認用

Excelは以下の用途に限定することをお勧めします:

  • データの初期確認
  • 数百点程度の小規模データ
  • 一時的な可視化

本格的な研究では、次に紹介するgnuplotやmatplotlibを使いましょう。


3. gnuplot - 研究者御用達のグラフ作成ツール

gnuplotは無料で使える強力なグラフ作成ツールです。コマンドベースで最初は戸惑うかもしれませんが、一度覚えれば効率的に美しいグラフが作成できます。

なぜgnuplotなのか

  • どんな環境でも動作:Windows、Mac、Linux、すべてで同じように使える
  • 軽量・高速:数万点のデータでも瞬時に描画
  • 再現性:スクリプトで完全に再現可能
  • 論文品質:多くの研究者が使用、学術誌の要求を満たす品質
  • 無料:ライセンス費用の心配なし

インストール方法

Windows

最も簡単な方法は公式インストーラを使用することです:

  1. 公式サイトから「Download」をクリック
  2. 「gp###-win64-mingw.exe」(###はバージョン番号)をダウンロード
  3. インストーラを実行し、指示に従う
  4. 環境変数PATHにgnuplotのbinフォルダを追加(オプション)

または、Chocolateyを使用している場合:

choco install gnuplot

macOS

Homebrewを使用(推奨):

brew install gnuplot

インストール確認:

gnuplot --version

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install gnuplot

Linux (CentOS/RHEL/Fedora)

sudo yum install gnuplot

基本的な使い方

1. インタラクティブモード

ターミナルでgnuplotと入力すると対話モードが起動します:

$ gnuplot

    G N U P L O T
    Version 5.4 patchlevel 2

gnuplot> 

簡単なテスト:

gnuplot> plot sin(x)

終了するには:

gnuplot> exit

2. 基本的な散布図の作成

IMUデータ(imu_data.csv)を使った最初の一歩:

# CSVファイルの場合、データセパレータをカンマに指定
set datafile separator ","

# ファイルからデータを読み込んで散布図を表示
plot "imu_data.csv" using 1:2 with points

このコマンドの意味:

  • set datafile separator ",":CSVファイル(カンマ区切り)を読み込む設定
  • plot:グラフを描画
  • "imu_data.csv":データファイル名
  • using 1:2:1列目をX軸、2列目をY軸に使用(u 1:2と省略可能)
  • with points:点(散布図)で表示(w pと省略可能)

gnuplotコマンドの省略記法

gnuplotでは多くのコマンドを省略できます:

# 完全形
plot "data.csv" using 1:2 with points pointtype 7 pointsize 0.5 title "Data"

# 省略形
plot "data.csv" u 1:2 w p pt 7 ps 0.5 t "Data"

# よく使う省略形
usingu
withw
pointtypept
pointsizeps
linewidthlw
linetypelt
titlet
notitle → not

省略形を使った例:

# 3軸プロットの省略版
plot "imu_data.csv" u 1:2 w p pt 7 ps 0.3 lc rgb "red" t "X-axis", \
     "imu_data.csv" u 1:3 w p pt 5 ps 0.3 lc rgb "green" t "Y-axis", \
     "imu_data.csv" u 1:4 w p pt 9 ps 0.3 lc rgb "blue" t "Z-axis"

データファイルの区切り文字について

データファイルの形式に応じて区切り文字を指定する必要があります:

# CSVファイル(カンマ区切り)
set datafile separator ","

# TSVファイル(タブ区切り)
set datafile separator "\t"

# スペース区切り(デフォルト)
set datafile separator " "

# 複数の区切り文字(スペースとタブ)
set datafile separator whitespace

# セミコロン区切り(一部のヨーロッパ系CSV)
set datafile separator ";"

区切り文字を戻すとき:

# デフォルト(スペースとタブ)に戻す
set datafile separator whitespace

3. スクリプトファイルの作成

実用的には、コマンドをファイルに保存して実行します。

plot_basic.gnuplotを作成:

# gnuplotスクリプトの基本構造

# CSVファイルの区切り文字を設定
set datafile separator ","

# 出力設定(PNG画像として保存)
set terminal pngcairo size 800,600 font "Arial,12"
set output "imu_basic.png"

# グラフのタイトルと軸ラベル
set title "IMU Angular Velocity (X-axis)"
set xlabel "Time [s]"
set ylabel "Angular Velocity [deg/s]"

# グリッド表示
set grid

# データのプロット
plot "imu_data.csv" using 1:2 with points pointtype 7 pointsize 0.5 title "X-axis"

# 出力をリセット(重要!)
unset output

実行方法:

gnuplot plot_basic.gnuplot

実用的な例

1. 3軸同時プロット

plot_3axis.gnuplot

# CSVファイルの区切り文字を設定
set datafile separator ","

# 出力設定
set terminal pngcairo size 1000,600 font "Arial,12"
set output "imu_3axis.png"

# グラフ設定
set title "IMU Angular Velocity (3-axis)"
set xlabel "Time [s]"
set ylabel "Angular Velocity [deg/s]"
set grid
set key right top  # 凡例の位置

# 3軸すべてをプロット
plot "imu_data.csv" using 1:2 with points pt 7 ps 0.3 lc rgb "red" title "X-axis", \
     "imu_data.csv" using 1:3 with points pt 7 ps 0.3 lc rgb "green" title "Y-axis", \
     "imu_data.csv" using 1:4 with points pt 7 ps 0.3 lc rgb "blue" title "Z-axis"

unset output

コマンドの説明: - pt 7:ポイントタイプ(7は塗りつぶし円) - ps 0.3:ポイントサイズ - lc rgb "red":線の色 - \:コマンドの継続

2. 時間範囲を限定した表示

特定の時間範囲だけを拡大表示:

# X軸(時間)の範囲を10〜20秒に限定
set xrange [10:20]

# Y軸も必要に応じて設定
set yrange [-30:30]

# 再プロット
replot

3. 複数のグラフを並べる(マルチプロット)

plot_multiplot.gnuplot

set terminal pngcairo size 800,900 font "Arial,10"
set output "imu_multiplot.png"

# 3行1列のレイアウト
set multiplot layout 3,1

# 1つ目のグラフ(X軸)
set title "X-axis"
set xlabel ""  # 最後のグラフ以外はX軸ラベルを省略
set ylabel "Angular Velocity [deg/s]"
plot "imu_data.csv" using 1:2 with points pt 7 ps 0.3 lc rgb "red" notitle

# 2つ目のグラフ(Y軸)
set title "Y-axis"
plot "imu_data.csv" using 1:3 with points pt 7 ps 0.3 lc rgb "green" notitle

# 3つ目のグラフ(Z軸)
set title "Z-axis"
set xlabel "Time [s]"  # 最後のグラフにはX軸ラベルを表示
plot "imu_data.csv" using 1:4 with points pt 7 ps 0.3 lc rgb "blue" notitle

unset multiplot
unset output

よく使うオプション

ポイントタイプ(pt)

  • 1: +
  • 2: ×
  • 3: *
  • 4: □
  • 5: ■
  • 6: ○
  • 7: ●
  • 8: △
  • 9: ▽

線の種類(lt)

  • 1: 実線
  • 2: 破線
  • 3: 点線

色の指定

# 色名で指定
lc rgb "red"
lc rgb "blue"
lc rgb "forest-green"

# 16進数で指定
lc rgb "#FF0000"  # 赤
lc rgb "#0000FF"  # 青
lc rgb "#808080"  # グレー

デバッグのコツ

  1. エラーが出たら

    • ファイルパスを確認(相対パス/絶対パス)
    • データファイルの形式を確認(区切り文字)
    • カラム番号を確認(1から始まる)
  2. グラフが表示されない

    • set outputを忘れていないか
    • unset outputを忘れていないか
    • ターミナルタイプが正しいか
  3. インタラクティブモードで確認

   gnuplot> show terminal
   gnuplot> test  # テストパターンを表示

便利なコマンド集

# データファイルの統計情報を表示
stats "imu_data.csv" using 2

# データの一部を確認
plot "imu_data.csv" using 1:2 every 100  # 100点ごとに表示

# 移動平均を追加
plot "imu_data.csv" using 1:2 with points, \
     "imu_data.csv" using 1:2 smooth bezier

# CSVファイル(カンマ区切り)の場合
set datafile separator ","

# タブ区切りに戻す
set datafile separator "\t"

次のステップ

gnuplotの基本をマスターしたら、以下にも挑戦してみましょう:

  • フィッティング機能(fitコマンド)
  • 3Dプロット(splotコマンド)
  • アニメーション作成
  • LaTeX連携(epslatexターミナル)

gnuplotは奥が深いツールですが、ここで紹介した内容だけでも研究に必要なグラフの大部分は作成できます。


4. matplotlib - Pythonで自在にグラフを操る

matplotlibは、Pythonで最も広く使われているグラフ描画ライブラリです。Pythonに慣れた学生なら、データ処理と可視化を統合できる柔軟性の高さが魅力となるでしょう。

なぜmatplotlibなのか

  • Pythonプログラムとの統合:データ処理と可視化を1つのスクリプトで実行
  • 柔軟性:あらゆるカスタマイズが可能
  • 豊富な機能:統計処理、フィッティング、アニメーションなど
  • 活発なコミュニティ:豊富なドキュメントとサンプル
  • Jupyter Notebookとの相性:インタラクティブな分析が可能

Python環境の構築とインストール

1. Pythonのインストール

Windows
  1. Python公式サイトから最新版をダウンロード
  2. インストーラを実行
  3. 重要: 「Add Python to PATH」に必ずチェック
  4. 「Install Now」をクリック

確認方法(コマンドプロンプトで実行):

python --version
macOS

方法1:公式インストーラ

  1. Python公式サイトからmacOS用インストーラをダウンロード
  2. .pkgファイルを実行してインストール

方法2:Homebrewを使用(推奨)

# Homebrewがインストール済みの場合
brew install python3

# 確認
python3 --version
Linux (Ubuntu/Debian)
# Python3は通常プリインストールされているが、最新版にする場合
sudo apt update
sudo apt install python3 python3-pip

# 確認
python3 --version
pip3 --version
Linux (CentOS/RHEL/Fedora)
# Python3のインストール
sudo yum install python3 python3-pip

# または(Fedora)
sudo dnf install python3 python3-pip

# 確認
python3 --version

2. 必要なパッケージのインストール

Windows

コマンドプロンプトで実行:

# pipを最新版に更新
python -m pip install --upgrade pip

# 必要なパッケージをインストール
pip install matplotlib numpy pandas
macOS/Linux

ターミナルで実行:

# pipを最新版に更新
python3 -m pip install --upgrade pip

# 必要なパッケージをインストール
pip3 install matplotlib numpy pandas
仮想環境の使用(推奨)

プロジェクトごとに独立した環境を作ることで、パッケージの競合を避けられます:

# 仮想環境の作成(WindowsとmacOS/Linux共通)
python -m venv myenv

# 仮想環境の有効化
# Windows:
myenv\Scripts\activate
# macOS/Linux:
source myenv/bin/activate

# パッケージのインストール(仮想環境内で)
pip install matplotlib numpy pandas

# 仮想環境の無効化
deactivate

3. インストールの確認

以下のコマンドでインストールが正しく完了したか確認:

# Pythonインタープリタを起動
python

# 各パッケージのインポートとバージョン確認
>>> import matplotlib
>>> print(matplotlib.__version__)
>>> import numpy as np
>>> print(np.__version__)
>>> import pandas as pd
>>> print(pd.__version__)
>>> exit()

トラブルシューティング:

  • command not foundエラー: PATHが通っていない可能性
  • No module namedエラー: パッケージのインストールが失敗している
  • 権限エラー: --userオプションを追加(pip install --user matplotlib

基本的な使い方

1. 最小限のコードで散布図を作成

plot_simple.py

import matplotlib.pyplot as plt

# データの準備(例:時刻と角速度)
time = [0, 1, 2, 3, 4, 5]
angular_velocity = [10.2, 15.1, 12.3, 18.5, 14.2, 16.8]

# 散布図の作成
plt.scatter(time, angular_velocity)
plt.xlabel('Time [s]')
plt.ylabel('Angular Velocity [deg/s]')
plt.title('Simple Scatter Plot')
plt.show()

2. CSVファイルからデータを読み込む(NumPyを使用)

plot_numpy.py

import matplotlib.pyplot as plt
import numpy as np

# CSVファイルの読み込み(NumPy使用)
data = np.loadtxt('imu_data.csv', delimiter=',')

# 各列を変数に格納
time = data[:, 0]        # 1列目:時刻
gyro_x = data[:, 1]      # 2列目:X軸角速度
gyro_y = data[:, 2]      # 3列目:Y軸角速度
gyro_z = data[:, 3]      # 4列目:Z軸角速度

# 散布図の作成
plt.figure(figsize=(10, 6))
plt.scatter(time, gyro_x, s=1, alpha=0.5)
plt.xlabel('Time [s]')
plt.ylabel('Angular Velocity [deg/s]')
plt.title('IMU X-axis Angular Velocity')
plt.grid(True, alpha=0.3)
plt.savefig('imu_numpy.png', dpi=300)
plt.show()

3. pandasを使った読み込み(より便利)

pandasは、データ分析を効率的に行うためのライブラリです。CSVファイルの読み込みやデータの操作が簡単になります。

plot_pandas.py

import matplotlib.pyplot as plt
import pandas as pd

# pandasでCSVファイルを読み込む
# names引数で列名を指定(CSVにヘッダーがない場合)
data = pd.read_csv('imu_data.csv', 
                   names=['time', 'gyro_x', 'gyro_y', 'gyro_z'])

# データの確認(最初の5行を表示)
print(data.head())

# 基本統計量の確認
print(data.describe())

# 散布図の作成
plt.figure(figsize=(10, 6))
plt.scatter(data['time'], data['gyro_x'], s=1, alpha=0.5)
plt.xlabel('Time [s]')
plt.ylabel('Angular Velocity [deg/s]')
plt.title('IMU X-axis Angular Velocity')
plt.grid(True, alpha=0.3)
plt.savefig('imu_pandas.png', dpi=300)
plt.show()

pandasの利点:

  • data['time']のように列名でアクセスできる
  • data.head()で最初の数行を確認できる
  • data.describe()で統計情報を一覧できる
  • 欠損値の処理が簡単

実用的な例

1. 3軸同時プロット

plot_3axis.py

import matplotlib.pyplot as plt
import pandas as pd

# データの読み込み
data = pd.read_csv('imu_data.csv', 
                   names=['time', 'gyro_x', 'gyro_y', 'gyro_z'])

# 図の作成
plt.figure(figsize=(12, 6))

# 3軸を異なる色でプロット
plt.scatter(data['time'], data['gyro_x'], s=0.5, alpha=0.6, 
            color='red', label='X-axis')
plt.scatter(data['time'], data['gyro_y'], s=0.5, alpha=0.6, 
            color='green', label='Y-axis')
plt.scatter(data['time'], data['gyro_z'], s=0.5, alpha=0.6, 
            color='blue', label='Z-axis')

# グラフの装飾
plt.xlabel('Time [s]')
plt.ylabel('Angular Velocity [deg/s]')
plt.title('IMU Angular Velocity - 3 Axes')
plt.legend()
plt.grid(True, alpha=0.3)

# 保存と表示
plt.savefig('imu_3axis.png', dpi=300, bbox_inches='tight')
plt.show()

2. サブプロット(複数のグラフを並べる)

plot_subplots.py

import matplotlib.pyplot as plt
import pandas as pd

# データの読み込み
data = pd.read_csv('imu_data.csv', 
                   names=['time', 'gyro_x', 'gyro_y', 'gyro_z'])

# 3行1列のサブプロットを作成
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 10), 
                                     sharex=True)

# X軸
ax1.scatter(data['time'], data['gyro_x'], s=0.5, alpha=0.6, color='red')
ax1.set_ylabel('X-axis [deg/s]')
ax1.set_title('IMU Angular Velocity')
ax1.grid(True, alpha=0.3)

# Y軸
ax2.scatter(data['time'], data['gyro_y'], s=0.5, alpha=0.6, color='green')
ax2.set_ylabel('Y-axis [deg/s]')
ax2.grid(True, alpha=0.3)

# Z軸
ax3.scatter(data['time'], data['gyro_z'], s=0.5, alpha=0.6, color='blue')
ax3.set_ylabel('Z-axis [deg/s]')
ax3.set_xlabel('Time [s]')
ax3.grid(True, alpha=0.3)

# レイアウトの調整
plt.tight_layout()

# 保存と表示
plt.savefig('imu_subplots.png', dpi=300, bbox_inches='tight')
plt.show()

3. データ処理と可視化の統合

plot_with_processing.py

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# データの読み込み
data = pd.read_csv('imu_data.csv', 
                   names=['time', 'gyro_x', 'gyro_y', 'gyro_z'])

# データ処理:移動平均の計算
window_size = 50
data['gyro_x_smooth'] = data['gyro_x'].rolling(window=window_size, 
                                                center=True).mean()

# フィルタリング:異常値の除去
threshold = 3 * data['gyro_x'].std()
mean_val = data['gyro_x'].mean()
data['gyro_x_filtered'] = data['gyro_x'].where(
    abs(data['gyro_x'] - mean_val) < threshold, np.nan)

# 可視化
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True)

# 上段:生データと移動平均
ax1.scatter(data['time'], data['gyro_x'], s=0.5, alpha=0.3, 
            color='gray', label='Raw data')
ax1.plot(data['time'], data['gyro_x_smooth'], color='red', 
         linewidth=2, label=f'Moving average (window={window_size})')
ax1.set_ylabel('Angular Velocity [deg/s]')
ax1.set_title('Data Smoothing Example')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 下段:異常値除去
ax2.scatter(data['time'], data['gyro_x_filtered'], s=0.5, 
            alpha=0.6, color='blue')
ax2.set_xlabel('Time [s]')
ax2.set_ylabel('Filtered Angular Velocity [deg/s]')
ax2.set_title('Outlier Removal Example')
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('imu_processing.png', dpi=300, bbox_inches='tight')
plt.show()

# 統計情報の出力
print(f"Original data points: {len(data)}")
print(f"Filtered data points: {data['gyro_x_filtered'].notna().sum()}")
print(f"Removed outliers: {data['gyro_x_filtered'].isna().sum()}")

よく使う設定とテクニック

1. 図のサイズとDPI設定

# 図のサイズ(インチ単位)
plt.figure(figsize=(10, 6))

# 保存時の解像度
plt.savefig('figure.png', dpi=300)

2. 散布図のマーカー設定

# s: マーカーサイズ
# alpha: 透明度(0-1)
# marker: マーカーの形
plt.scatter(x, y, s=10, alpha=0.5, marker='o')

3. 色の指定

# 色名
plt.scatter(x, y, color='red')

# RGB値
plt.scatter(x, y, color='#FF5733')

# カラーマップ
plt.scatter(x, y, c=z, cmap='viridis')  # zの値で色分け

4. 日本語フォントの設定(必要な場合)

import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Hiragino Sans', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'VL PGothic', 'Noto Sans CJK JP']

インタラクティブな操作

Jupyter NotebookやIPythonを使用している場合:

%matplotlib notebook  # インタラクティブモード
# または
%matplotlib inline   # 静的表示(デフォルト)

デバッグのコツ

  1. グラフが表示されない
   plt.show()  # 最後に必ず実行
  1. メモリ不足(大量データ)
   # データを間引く
   plt.scatter(time[::10], data[::10])  # 10点ごと
  1. 図が重なる
   plt.clf()  # 現在の図をクリア
   plt.close('all')  # すべての図を閉じる

まとめ

matplotlibは学習曲線がやや急ですが、一度慣れれば非常に強力なツールです。特に:

  • データ処理と可視化を統合できる
  • 複雑な解析結果を視覚化できる
  • 論文品質のグラフを作成できる
  • 再現性のある研究ワークフローを構築できる

Pythonでデータ解析を行っているなら、matplotlibは必須のツールと言えるでしょう。


5. 論文用グラフ作成のベストプラクティス

学会発表や論文投稿では、グラフの品質が研究の印象を大きく左右します。ここでは、論文品質のグラフを作成するための重要なポイントを解説します。

ファイル形式の選択

ベクター形式(推奨)

  • PDF: 最も汎用性が高く、LaTeXとの相性も良い
  • EPS: 伝統的な論文用形式、一部の学会で指定される

ベクター形式の利点: - 拡大・縮小しても品質が劣化しない - ファイルサイズが小さい(図形ベースの場合) - 印刷品質が高い

ラスター形式(やむを得ない場合)

  • PNG: 可逆圧縮で品質劣化なし
  • TIFF: 一部の学会で要求される

ラスター形式使用時の注意: - 解像度は300dpi以上(印刷用) - Web表示用でも150dpi以上を推奨 - JPEGは避ける(非可逆圧縮のため)

フォントとラベルの扱い

英語表記を推奨する理由

日本語フォントは環境依存の問題が多いため、論文では英語表記を推奨します:

# 推奨
Title: "IMU Angular Velocity Measurement"
X-axis: "Time [s]"
Y-axis: "Angular Velocity [deg/s]"

# 避けるべき
Title: "IMU角速度測定"
X-axis: "時間 [秒]"
Y-axis: "角速度 [度/秒]"

日本語を使う必要がある場合

gnuplotでの日本語対応
# 日本語フォントの設定(Windows)
set terminal pdfcairo font "MS Gothic,10"

# 日本語フォントの設定(Mac)
set terminal pdfcairo font "Hiragino Sans,10"

# 日本語フォントの設定(Linux)
set terminal pdfcairo font "IPAGothic,10"

# 文字化けする場合はUTF-8エンコーディングを指定
set encoding utf8
matplotlibでの日本語対応
import matplotlib.pyplot as plt
import matplotlib as mpl

# 日本語フォントの設定
# 方法1: rcParamsで設定
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Hiragino Sans', 'Yu Gothic', 'Meirio', 
                                   'Takao', 'IPAexGothic', 'IPAPGothic', 
                                   'VL PGothic', 'Noto Sans CJK JP']

# 方法2: フォントを直接指定
from matplotlib import font_manager
# Windowsの場合
font_path = 'C:/Windows/Fonts/msgothic.ttc'
# Macの場合
# font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc'
font_prop = font_manager.FontProperties(fname=font_path)

plt.xlabel('時間 [秒]', fontproperties=font_prop)
plt.ylabel('角速度 [度/秒]', fontproperties=font_prop)

トラブルシューティング:

# 利用可能なフォントを確認
import matplotlib.font_manager
for font in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'):
    print(font)

gnuplotでの論文用設定

publication_gnuplot.gnuplot:

# 論文用の基本設定
set terminal pdfcairo size 3.5in,2.5in font "Times,10" linewidth 2
set output "figure1.pdf"

# マージン設定(図の周りの余白を適切に)
set lmargin at screen 0.15
set rmargin at screen 0.95
set bmargin at screen 0.15
set tmargin at screen 0.9

# 軸の設定
set border linewidth 1.5
set tics scale 0.75
set mxtics 5
set mytics 5

# グリッドは控えめに
set grid xtics ytics mxtics mytics lc rgb "#E0E0E0" lt 1 lw 0.5

# モノクロでも区別できるマーカー
set style line 1 pt 7 ps 0.3 lc rgb "black"
set style line 2 pt 5 ps 0.3 lc rgb "black"
set style line 3 pt 9 ps 0.3 lc rgb "black"

# データのプロット
plot "data1.csv" using 1:2 with points ls 1 title "Dataset 1", \
     "data2.csv" using 1:2 with points ls 2 title "Dataset 2", \
     "data3.csv" using 1:2 with points ls 3 title "Dataset 3"

unset output

カラー版の場合(色覚多様性に配慮):

# カラーバリアフリーな配色
set style line 1 pt 7 ps 0.3 lc rgb "#E69F00"  # オレンジ
set style line 2 pt 5 ps 0.3 lc rgb "#56B4E9"  # スカイブルー
set style line 3 pt 9 ps 0.3 lc rgb "#009E73"  # 緑
set style line 4 pt 11 ps 0.3 lc rgb "#F0E442" # 黄
set style line 5 pt 13 ps 0.3 lc rgb "#0072B2" # 青

matplotlibでの論文用設定

publication_matplotlib.py:

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

# 論文用の設定
def setup_publication_style():
    # フィギュアサイズ(IEEE 2カラム論文の1カラム幅)
    fig_width_pt = 246.0  # LaTeXの\columnwidthから取得
    inches_per_pt = 1.0/72.27
    golden_mean = (np.sqrt(5)-1.0)/2.0  # 黄金比
    fig_width = fig_width_pt*inches_per_pt
    fig_height = fig_width*golden_mean
    
    params = {
        'figure.figsize': (fig_width, fig_height),
        'font.size': 10,
        'axes.labelsize': 10,
        'axes.titlesize': 11,
        'xtick.labelsize': 9,
        'ytick.labelsize': 9,
        'legend.fontsize': 9,
        'lines.linewidth': 1.5,
        'lines.markersize': 3,
        'figure.dpi': 150,
        'savefig.dpi': 300,
        'text.usetex': False,  # LaTeX使用(要LaTeX環境)
        'font.family': 'serif',
        'font.serif': ['Times'],
        'axes.grid': True,
        'grid.alpha': 0.3,
        'grid.linewidth': 0.5,
    }
    
    mpl.rcParams.update(params)

# 設定を適用
setup_publication_style()

# データの準備
data = pd.read_csv('imu_data.csv', names=['time', 'x', 'y', 'z'])

# グラフの作成
fig, ax = plt.subplots()

# モノクロでも区別できるマーカー
markers = ['o', 's', '^']
colors = ['#E69F00', '#56B4E9', '#009E73']  # カラーバリアフリー配色

# データのプロット
ax.scatter(data['time'], data['x'], s=1, alpha=0.6, 
           marker=markers[0], color=colors[0], label='X-axis')
ax.scatter(data['time'], data['y'], s=1, alpha=0.6, 
           marker=markers[1], color=colors[1], label='Y-axis')
ax.scatter(data['time'], data['z'], s=1, alpha=0.6, 
           marker=markers[2], color=colors[2], label='Z-axis')

# 軸の設定
ax.set_xlabel('Time [s]')
ax.set_ylabel('Angular Velocity [deg/s]')
ax.legend(loc='best', frameon=True, fancybox=False, framealpha=0.9)

# 余白の調整
plt.tight_layout(pad=0.1)

# 保存(複数形式)
plt.savefig('figure1.pdf', format='pdf', bbox_inches='tight')
plt.savefig('figure1.eps', format='eps', bbox_inches='tight')
plt.savefig('figure1.png', format='png', dpi=300, bbox_inches='tight')

LaTeXでの図の埋め込み

% PDFの場合
\begin{figure}[htbp]
    \centering
    \includegraphics[width=0.8\columnwidth]{figure1.pdf}
    \caption{IMU angular velocity measurements over time.}
    \label{fig:imu_data}
\end{figure}

% 2カラム論文で1カラム幅の図
\begin{figure}[htbp]
    \centering
    \includegraphics[width=\columnwidth]{figure1.pdf}
    \caption{IMU angular velocity measurements.}
    \label{fig:imu_data}
\end{figure}

% 2カラム論文で2カラム幅の図
\begin{figure*}[htbp]
    \centering
    \includegraphics[width=\textwidth]{figure1.pdf}
    \caption{IMU angular velocity measurements.}
    \label{fig:imu_data}
\end{figure*}

論文投稿前のチェックリスト

必須項目

  • [ ] ファイル形式は指定に従っているか(PDF/EPS/TIFF等)
  • [ ] 解像度は300dpi以上か(ラスター形式の場合)
  • [ ] フォントサイズは読みやすいか(最小8pt以上)
  • [ ] 軸ラベルと単位が明記されているか
  • [ ] 凡例は適切に配置されているか
  • [ ] グレースケールで印刷しても区別できるか

推奨項目

  • [ ] 図のサイズは論文のカラム幅に合っているか
  • [ ] 不要な装飾(3D効果、影など)を除去したか
  • [ ] データ点が多すぎて黒く潰れていないか
  • [ ] 色覚多様性に配慮した配色か
  • [ ] 図番号とキャプションの対応は正しいか

よくある失敗と対策

  1. 日本語の文字化け

    • 対策:英語表記にする、またはフォント埋め込みPDFを使用
  2. 図が小さすぎて見えない

    • 対策:論文のカラム幅を確認し、適切なサイズで作成
  3. データ点が重なって真っ黒

    • 対策:透明度(alpha)を設定、またはデータを間引く
  4. EPS形式で透明度が使えない

    • 対策:PDFを使用、または透明度を使わない表現に変更
  5. フォントが埋め込まれていない

    • 対策:PDF作成時にフォント埋め込みオプションを指定

論文用のグラフ作成は慣れが必要ですが、一度テンプレートを作れば使い回せます。早めに指導教員や先輩に確認してもらうことをお勧めします。


まとめ

3つのツールの使い分け

この記事では、Excel、gnuplot、matplotlibという3つのツールを紹介しましたが、最も重要なメッセージは「gnuplotやmatplotlibに早く慣れて、より効率的な研究を目指しましょう」ということです。

より高度なツールを習得する利点

  • 研究の効率性: スクリプトベースのツールで作業を大幅に効率化
  • 再現性の確保: 同じ処理を何度でも正確に実行可能
  • スケーラビリティ: 大量データも問題なく処理
  • 論文品質: 研究にふさわしい高品質なグラフを作成

gnuplotとmatplotlibの使い分け

両方のツールをマスターした後の使い分け:

gnuplotを選ぶべき場面

  • 定型的なグラフ作成: 毎日同じ形式のデータを可視化
  • 軽量・高速処理: 大量データを素早く確認
  • 環境に依存しない: どんなマシンでも動作
  • バッチ処理: 自動化されたデータ処理パイプライン

matplotlibを選ぶべき場面

  • データ解析との統合: 統計処理と可視化を同時に実行
  • 複雑なカスタマイズ: 特殊な表現や高度な装飾が必要
  • インタラクティブ分析: Jupyter Notebookでの試行錯誤
  • 機械学習との連携: scikit-learn等との組み合わせ

学生へのエール

データの可視化をマスターすることは、研究者としての基礎体力を身につけることです。

最初は「面倒だな」と感じるかもしれません。Excelでちゃちゃっと作った方が早いと思うこともあるでしょう。しかし、gnuplotやmatplotlibを覚える投資は、必ず将来の研究活動で何倍にもなって返ってきます。

特に:

  • 研究の速度が上がる: データ解析→可視化のサイクルが高速化
  • 発見が増える: 美しいグラフは新たな洞察をもたらす
  • 論文の質が向上: 査読者に良い印象を与える
  • 他の研究者との差別化: 技術力で研究の質を底上げ

次のステップ

この記事をマスターした後に挑戦すべきこと:

gnuplotの発展

  • 3Dプロット: splotコマンドの活用
  • アニメーション: 時系列データの動的表現
  • フィッティング: fitコマンドでデータの数式化
  • マクロ作成: よく使う処理の自動化

matplotlibの発展

  • seaborn: 統計的可視化ライブラリ
  • plotly: インタラクティブなWebベースグラフ
  • bokeh: 大規模データの可視化
  • mayavi: 3D科学データの可視化

他の可視化ツール

  • R + ggplot2: 統計解析特化
  • D3.js: Web上での高度な可視化
  • Tableau: ビジネス分析ツール

最後に

データの可視化は、数値の海に隠された真実を「見える化」する技術です。正しく、美しく、効率的にグラフを作ることができれば、あなたの研究はより説得力を持ち、より多くの人に価値を伝えることができるでしょう。

今日から折れ線グラフを卒業し、散布図の世界へ足を踏み入れてください。そして、gnuplotやmatplotlibを使いこなせるようになって、本当に研究に役立つツールを身につけてください。

皆さんの研究が、美しいグラフとともに世界を変える日を楽しみにしています。


付録:サンプルデータの作成方法

この記事で使用するIMUデータのサンプルを生成するPythonスクリプトです。実際にIMUを用意しなくても、リアルなセンサデータの特徴を持ったサンプルデータで練習できます。

データ生成スクリプト

generate_imu_data.py

import numpy as np
import pandas as pd

# パラメータ設定
duration = 60  # 測定時間[秒]
sampling_rate = 100  # サンプリングレート[Hz]
noise_level = 0.5  # ノイズレベル[deg/s]

# 時刻配列の生成
time = np.arange(0, duration, 1/sampling_rate)

# X軸:ゆっくりとした正弦波運動(ゆっくりとした回転)
gyro_x = 10 * np.sin(2 * np.pi * 0.1 * time) + \
          noise_level * np.random.randn(len(time))

# Y軸:ステップ応答(急激な動きと停止)
gyro_y = np.zeros_like(time)
gyro_y[time > 20] = 15    # 20秒後に急激な回転開始
gyro_y[time > 40] = -10   # 40秒後に逆方向の回転
gyro_y += noise_level * np.random.randn(len(time))

# Z軸:ランダムウォーク(微小な振動の蓄積)
random_walk = np.cumsum(0.1 * np.random.randn(len(time)))
gyro_z = random_walk + noise_level * np.random.randn(len(time))

# データフレームの作成
data = pd.DataFrame({
    'time': time,
    'gyro_x': gyro_x,
    'gyro_y': gyro_y,
    'gyro_z': gyro_z
})

# CSVファイルとして保存(ヘッダーなし)
data.to_csv('imu_data.csv', index=False, header=False)

# 確認用の情報を出力
print(f"サンプルデータを生成しました: imu_data.csv")
print(f"データ点数: {len(data)}")
print(f"時間範囲: 0 - {duration}秒")
print(f"サンプリングレート: {sampling_rate} Hz")
print()
print("データの統計情報:")
print(data.describe())

スクリプトの実行方法

  1. 上記のコードをgenerate_imu_data.pyとして保存
  2. ターミナルまたはコマンドプロンプトで実行: bash python generate_imu_data.py
  3. imu_data.csvが生成されます

生成されるデータの特徴

  • 時刻: 0.01秒間隔(100Hz)で60秒分
  • X軸角速度: 周期10秒の正弦波(±10 deg/s)
  • Y軸角速度: 0-20秒は0、20-40秒は15 deg/s、40-60秒は-10 deg/s
  • Z軸角速度: ランダムウォーク(微小変動が蓄積)
  • ノイズ: 全軸に標準偏差0.5 deg/sのガウシアンノイズ

実データを使用する際の注意点

データ形式の確認

実際のIMUデータを使用する場合、以下を確認してください:

  1. 区切り文字: CSV(カンマ区切り)、TSV(タブ区切り)、スペース区切りなど
  2. ヘッダーの有無: 1行目にカラム名があるかどうか
  3. 単位の統一: 角速度の単位(deg/s、rad/s、rpm等)
  4. 欠損値の処理: NaN、空文字、特殊な値(-999等)の扱い
  5. 時刻の形式: Unix時刻、相対時刻、絶対時刻など

よくあるデータ問題と対処法

  1. 異なる区切り文字
   # タブ区切りの場合
   data = pd.read_csv('data.txt', sep='\t')
   
   # スペース区切りの場合
   data = pd.read_csv('data.txt', sep='\s+')
  1. ヘッダーがある場合
   # 1行目をヘッダーとして読み込み
   data = pd.read_csv('data.csv')
   
   # ヘッダーを無視
   data = pd.read_csv('data.csv', skiprows=1, names=['time', 'x', 'y', 'z'])
  1. 異常値の除去
   # 物理的に不可能な値を除去
   data = data[(data['gyro_x'] > -1000) & (data['gyro_x'] < 1000)]
   
   # 統計的外れ値の除去
   Q1 = data['gyro_x'].quantile(0.25)
   Q3 = data['gyro_x'].quantile(0.75)
   IQR = Q3 - Q1
   data = data[(data['gyro_x'] >= Q1 - 1.5*IQR) & (data['gyro_x'] <= Q3 + 1.5*IQR)]
  1. 単位の変換
   # rad/sからdeg/sに変換
   data['gyro_x_deg'] = data['gyro_x_rad'] * 180 / np.pi
   
   # 時刻をUnix時刻から相対時刻に変換
   data['time_rel'] = data['timestamp'] - data['timestamp'].iloc[0]

このサンプルデータを使って、記事中の各ツールでの可視化を実際に試してみてください。実データとの違いを理解することで、より実践的なスキルが身につきます。


この記事が、皆さんの研究活動に役立つことを願っています。正しいデータの可視化は、研究の質を大きく左右します。ぜひ、散布図を使った適切な時系列データの表現方法をマスターしてください!