やっぱり先のエントリでこのコードを動かすとmatplotlibのウィンドウが余計に出てしまうのは未解決と書きました。
そもそも、これは解決容易な問題かどうかです。これまで出回っているサンプルコードが自分のMac環境で正常に動作するか確認してみました。コードはこちらとこちらから使用しました。結論だけいうと、何の問題はありません。極めて正常に動作しています。つまりは、自分のコードが悪いという事です。
実は気になる心当たりがありました。
fig = matplotlib.pyplot.figure()実はこれはここのオリジナルのコードと意図的に変えています。
fig = matplotlib.figure.Figure()これを変えた理由は、作成したグラフをPyQtに埋め込んで表示すると同時に、グラフの画像ファイルを生成して保存する機能を盛り込みたかったからです。自分が修正したコードでは、figから画像ファイルを生成することができます。
fig.savefig(filename)ところが、ここをオリジナルのコードに戻しますと、matplotlibのウィンドウ複数表示がなくなり、目下の問題は解決します。要するに原因はココだったわけです。しかし、オリジナルに戻しますとfig.savefig()が使えなくなります。これでは元の木阿弥です。
解決する方法はありました。画像を生成する方法を変えればいいのです。以前から目にはなんとなく入っていたprint_figure()というものを使ってみます。こちらを参考にして修正してみます。グラフの画像ファイルを生成する部分はPyQtで表示するのとは別のバックエンド用canvasオブジェクトを生成するようにすればいいようです。
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig) canvas.print_figure(filename)以前のサンプルコードを修正したフルコードは以下のようになります。
#!/usr/bin/env python # -*- coding: utf-8 -*- # for command-line arguments import sys # Numpy functions for image creation import numpy # Matplotlib Figure object import matplotlib import matplotlib.pyplot # Python Qt4 bindings for GUI objects import PyQt4.QtGui # import the Qt4Agg FigureCanvas object, that binds Figure to # Qt4Agg backend. It also inherits from QWidget #from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas import matplotlib.backends.backend_qt4agg import matplotlib.backends.backend_agg # import the NavigationToolbar Qt4Agg widget #from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar class ApplicationWindow(PyQt4.QtGui.QMainWindow): """Example main window""" def __init__(self,figs): # initialization of Qt MainWindow widget PyQt4.QtGui.QMainWindow.__init__(self) # set window title self.setWindowTitle("Matplotlib Figure in a Qt4 Window With NavigationToolbar") # create a tab widget self.tab_widget = PyQt4.QtGui.QTabWidget(self) for fig, label in figs: # instantiate a widget, it will be the main one self.main_widget = PyQt4.QtGui.QWidget(self) self.tab_widget.addTab(self.main_widget, label) # create a vertical box layout widget vbl = PyQt4.QtGui.QVBoxLayout(self.main_widget) # instantiate our Matplotlib canvas widget qmc = matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg(fig) # instantiate the navigation toolbar ntb = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg( qmc, self.main_widget) # pack these widget into the vertical box vbl.addWidget(qmc) vbl.addWidget(ntb) # # set the focus on the main widget # self.tab_widget.setFocus() # set the central widget of MainWindow to main_widget self.setCentralWidget(self.tab_widget) def draw(): figs = [] # Standard Matplotlib code to generate the plot # fig = matplotlib.pyplot.figure() fig = matplotlib.figure.Figure() axes = fig.add_subplot(111) x = numpy.arange(0.0, 3.0, 0.01) y = numpy.cos(1*numpy.pi*x) axes.plot(x, y) figs.append((fig,"tab 1")) # fig = matplotlib.pyplot.figure() fig = matplotlib.figure.Figure() axes = fig.add_subplot(111) x = numpy.arange(0.0, 3.0, 0.01) y = numpy.cos(2*numpy.pi*x) axes.plot(x, y) figs.append((fig,"tab 2")) # fig = matplotlib.pyplot.figure() fig = matplotlib.figure.Figure() axes = fig.add_subplot(111) x = numpy.arange(0.0, 3.0, 0.01) y = numpy.cos(3*numpy.pi*x) axes.plot(x, y) figs.append((fig,"tab 3")) return figs # Create the GUI application qApp = PyQt4.QtGui.QApplication(sys.argv) figs = draw() # save image file of matplotlib graph canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(figs[0][0]) canvas.print_figure("qt4mpl.png") # Create the Matplotlib widget mpl = ApplicationWindow(figs) # show the widget mpl.show() # start the Qt main loop execution, exiting from this script # with the same return code of Qt application sys.exit(qApp.exec_())多分これで良さそうです。
0 件のコメント:
コメントを投稿