Edited at

Matplotlibのプロット上でのGUIでボックス領域選択による要素数のカウントし要素をCSV形式でクリップボードにコピーする

More than 1 year has passed since last update.


やりたいこと

Matplotlibのプロット上でのGUIで四角形領域を選択し、選択された領域内でプロットされた要素数を出力したい!!

更に、要素をCSV形式でクリップボードにコピーしたい


ソースコード

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.widgets import RectangleSelector
import pyperclip

class RectSelect(object):
def __init__(self, x, y, ax=None):
self.ax = ax or plt.gca()
self.x = x
self.y = y
self.rect = Rectangle((0,0), 0, 0, color='orange', alpha=0.5)
self.ax.add_patch(self.rect)
self.blc = np.zeros(2)
self.trc = np.zeros(2)

def selector(event):
if event.key in ['Q', 'q'] and selector.RS.active:
selector.RS.set_active(False)
if event.key in ['A', 'a'] and not selector.RS.active:
selector.RS.set_active(True)

selector.RS = RectangleSelector(self.ax, self.callback)
self.ax.figure.canvas.mpl_connect('key_press_event', selector)
self.ax.figure.canvas.mpl_connect('button_release_event', self.release)

def callback(self, eclick, erelease):
def _check(a, b):
if (a >= eclick.xdata and a <= erelease.xdata) and (b >= eclick.ydata and b <= erelease.ydata):
return True
else:
return False

count = 0
copy_text = ""
for x_i, y_j in zip(self.x, self.y):
if _check(x_i, y_j):
count += 1
copy_text += "{0},{1}\r\n".format(x_i, y_j)

pyperclip.copy(copy_text)
print count, "num"

def release(self, event):
self.rect.set_width(self.trc[0] - self.blc[0])
self.rect.set_height(self.trc[1] - self.blc[1])
self.rect.set_xy(self.blc)
self.ax.figure.canvas.draw()

x = np.random.random(20) * 10
y = np.random.random(20) * 10
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, '.')
region = RectSelect(x, y)
plt.show()


結果

適当にプロットし、マウスで領域を選択する

image.png

するとこんな感じに出力される。期待通りにピンク色の四角形領域の点の個数を数えられました(・ω・)v

image.png

追加

四角形領域選択後、選択した点の座標をCSV形式でクリップボードにコピーします


参考サイト