23
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PyQt5にmatplotlibを埋め込んで簡易画像ビューアを作る

Last updated at Posted at 2017-12-27

はじめに

PyQt5にmatplotlibのfigureを埋め込む方法はmatplotlibの公式で紹介されています。

user_interfaces example code: embedding_in_qt5.py

基本的にはFigureクラスをFigureCanvasQTAggクラスを介して、PyQt5のレイアウト(QVBoxLayoutやQHBoxLayout)に入れるというやり方です。

公式のようなFigureCanvasQTAggを継承するやり方は、データのやり取りなどで使いにくかったので、FigureCanvasQTAggクラスのインスタンスを直接PyQt5のレイアウトに追加する方法に変更しています。

結果

Dec-28-2017 00-40-12.gif

ソースコード

import sys
import os

import numpy as np
import matplotlib.pyplot as plt

from PyQt5 import QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

import glob
from PIL import Image

class Application(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        # UIの初期化
        self.initUI()

        # rootディレクトリ
        self.root = './Image/'
        # 拡張子
        self.ext = 'bmp'

        # ファイルを配置
        self.set_FileList()

        # 画像
        self.FileName = self.FileList.item(0).text()

        # 画像を読み込む
        self.load_ImageFile()

        # Figureの初期化
        self.initFigure()

        # ファイルを変更した時のイベント
        self.FileList.itemSelectionChanged.connect(self.FileList_Changed)
        
    # UIの初期化
    def initUI(self):
        # Figure用のWidget
        self.FigureWidget = QtWidgets.QWidget(self)
        # FigureWidgetにLayoutを追加
        self.FigureLayout = QtWidgets.QVBoxLayout(self.FigureWidget)
        # Marginを消す
        self.FigureLayout.setContentsMargins(0,0,0,0)

        # ファイルのリスト
        self.FileList = QtWidgets.QListWidget(self)

        # 配置
        self.setGeometry(0,0,900,600)
        self.FigureWidget.setGeometry(200,0,700,600)
        self.FileList.setGeometry(0,0,200,600)
    
    # Figureの初期化
    def initFigure(self):
        # Figureを作成
        self.Figure = plt.figure()
        # FigureをFigureCanvasに追加
        self.FigureCanvas = FigureCanvas(self.Figure)
        # LayoutにFigureCanvasを追加
        self.FigureLayout.addWidget(self.FigureCanvas)
        
        self.axis = self.Figure.add_subplot(1,1,1)
        self.axis_image = self.axis.imshow(self.image, cmap='gray')
        plt.axis('off')

    # ファイルを配置
    def set_FileList(self):
        # ファイルの読み込み
        Files = glob.glob(self.root+'*.'+self.ext)
        # ソート
        self.Files = sorted(Files)

        # ファイルリストに追加
        for file in self.Files: 
            self.FileList.addItem(os.path.basename(file))

    # ファイルを変更した時の関数
    def FileList_Changed(self):
        # 選択しているファイルの名前を取得
        self.FileName = self.FileList.selectedItems()[0].text()
        # 画像を読み込み
        self.load_ImageFile()
        # Figureを更新
        self.update_Figure()
    
    # 画像ファイルを読み込む
    def load_ImageFile(self):
        # 画像を開く
        image = Image.open(self.root + self.FileName)
        # numpy.ndarrayに
        self.image = np.asarray(image)

    # Figureを更新
    def update_Figure(self):
        self.axis_image.set_data(self.image)
        self.FigureCanvas.draw()
        
QApp = QtWidgets.QApplication(sys.argv)
app = Application()
app.show()
sys.exit(QApp.exec_())

解説

FigureCanvasQTAggクラスをFigureCanvasとしてimportします。

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

Figure用のWidget(QWidget : FigureWidget)にレイアウト(QVBoxLayout : FigureLayout)を追加します。

initUI
# Figure用のWidget
self.FigureWidget = QtWidgets.QWidget(self)
# FigureWidgetにLayoutを追加
self.FigureLayout = QtWidgets.QVBoxLayout(self.FigureWidget)

Figureを作成し、FigureCanvasに追加します。さらにFigureCanvasをレイアウト(FigureLayout)に追加します。

initFigure
# Figureを作成
self.Figure = plt.figure()
# FigureをFigureCanvasに追加
self.FigureCanvas = FigureCanvas(self.Figure)
# LayoutにFigureCanvasを追加
self.FigureLayout.addWidget(self.FigureCanvas)

ややこしいですが、全体の構成は以下のようになっています。
Picture7.png

色々模索してこのやり方に落ち着きましたが、もっとスマートな方法があればぜひ教えて頂きたいです。
それ以外はファイルを選択する度に画像を読み込んで、更新しているだけなので詳細は割愛します。

また画像は下記サイトのものを使用させて頂きました。

標準画像/サンプルデータ

再配布可能か確認していないので、プログラムを試したい方は、ソースコードと同じ階層のImageフォルダに画像を追加し、適当に拡張子を指定している箇所を変更して実行してみて下さい。

動作確認

OS : macOS High Sierra Version 10.13.2
Python : 3.6.2
matplotlib : 2.0.2
PyQt5 : 5.6.0

23
24
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
23
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?