LoginSignup
16
17

More than 5 years have passed since last update.

matplotlibだけで画像からマウスで指定した列と行を描画

Last updated at Posted at 2017-12-27

目的

・2次元データ(Ex. 画像)からマウスで指定した列と行の1次元データを描画したい

結果

Dec-27-2017 17-07-03.gif

ソースコード

import matplotlib as mpl

# Backendの指定 
mpl.use('Qt5Agg')
# mpl.use('MacOSX')

import matplotlib.pyplot as plt
import numpy as np

#----------------------------------
# matplotlibのデフォルトの設定
#----------------------------------
# フォントサイズ
plt.rcParams["font.size"] = 16
# 線幅の変更
plt.rcParams['lines.linewidth'] = 2
# gridのlinestyleを点線に
plt.rcParams["grid.linestyle"] = '--'
# xの範囲のマージンをなくす
plt.rcParams['axes.xmargin'] = 0

# マウスを押した時
def Press(event):
    global DragFlag
    # フラグをたてる
    DragFlag = True

# マウスを離した時
def Release(event):
    global DragFlag
    # フラグをたおす
    DragFlag = False

# マウスをドラッグした時
def Drag(event):        
    global cxid,cyid,DragFlag

    # ドラッグしていなければ終了
    if DragFlag == False:
        return

    # Noneなら終了
    if (event.xdata is None) and (event.ydata is None):
        return

    # xとyの座標
    xdata = event.xdata
    ydata = event.ydata

    # 現在の軸
    gca = event.inaxes

    # XY軸のとき
    if gca is XYAxis:
        cx = xdata
        cy = ydata

        # 現在のid
        cxid = int(round(cx))
        cyid = int(round(cy))

        # 軸の更新
        XYAxis_vLine.set_xdata(cx)
        XAxis_vLine.set_xdata(cx)

        XYAxis_hLine.set_ydata(cy)
        YAxis_vLine.set_xdata(cy)

        XLine.set_ydata(Z[cyid, :])
        YLine.set_ydata(Z[:, cxid])

    # X軸のとき
    elif gca is XAxis:
        cx = xdata

        # 現在のid
        cxid = int(round(cx))

        # 軸の更新
        XYAxis_vLine.set_xdata(cx)
        XAxis_vLine.set_xdata(cx)
        YLine.set_ydata(Z[:,cxid])

    # Y軸のとき
    elif gca is YAxis:
        cy = xdata

        # 現在のid
        cyid = int(round(cy))

        # 軸の更新
        XYAxis_hLine.set_ydata(cy)
        YAxis_vLine.set_xdata(cy)
        XLine.set_ydata(Z[cyid,:])

    # タイトルの更新
    XYAxis.set_title("%d" % Z[cyid,cxid])

    # 図を描画
    plt.draw()

#----------------------------------
# 画像
#----------------------------------
from PIL import Image
fnm = 'lena.tif'
img = Image.open(fnm)

# numpy.ndarrayに
Z = np.asarray(img)
# 平均
Z = np.mean(Z,axis=2).astype(int)
# y軸反転
Z = Z[::-1,:]

#----------------------------------
# 初期化
#----------------------------------
# 現在のxとy
cx = 0
cy = 0

# 現在のxとyのindex
cxid = 0
cyid = 0

# zの範囲
zlm = [0, 255]

# ドラッグしているかのフラグ
DragFlag = False

#----------------------------------
# Plot
#----------------------------------
plt.figure(figsize=(12,4))

# XYAxis
#-------------------------------------------------------------------------------
XYAxis = plt.subplot(1,3,1)

# 画像を描画
plt.imshow(Z,cmap='gray', origin='lower')

# 縦線
XYAxis_vLine = XYAxis.axvline(cx, color='k',linestyle='--')
# 横線
XYAxis_hLine = XYAxis.axhline(cy, color='k',linestyle='--')

# zの範囲
plt.clim(zlm)

# ラベル
plt.xlabel('x')
plt.ylabel('y')

# タイトル
XYAxis.set_title("%d" % Z[cyid,cxid])

# XAxis
#-------------------------------------------------------------------------------
XAxis = plt.subplot(1,3,2)

# X軸をプロット
XLine, = XAxis.plot(Z[0,:],'-')

# 縦線
XAxis_vLine = XAxis.axvline(cx, color='k', linestyle='--')

# # y軸の範囲
plt.ylim(zlm)

# ラベル
plt.xlabel('x')
plt.ylabel('z')

# grid
plt.grid()

# YAxis
#-------------------------------------------------------------------------------
YAxis = plt.subplot(1,3,3)

# Y軸をプロット
YLine,= YAxis.plot(Z[:,0], '-')

# 縦線
YAxis_vLine = YAxis.axvline(cx, color='k', linestyle='--')

# y軸の範囲
plt.ylim(zlm)

# ラベル
plt.xlabel('y')
plt.ylabel('z')

# grid
plt.grid()

# 共通の設定
#-------------------------------------------------------------------------------

# レイアウトを整える
plt.tight_layout()

# イベントの登録
plt.connect('button_press_event', Press)     # マウスを押した時
plt.connect('motion_notify_event', Drag)     # マウスをドラッグした時
plt.connect('button_release_event', Release) # マウスを離した時

# 描画
plt.show()

動作確認

mac

Python 3.6.2
matplotlib 2.0.2
backend : MacOSX and Qt5Agg

参考画像

Picture3.png

参考文献

matplotlibの階層構造を知ると幸せになれる(かもしれない)

Event handling and picking

コメント

もしご要望がありましたらソースコードの解説を書きます!

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17