質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4273閲覧

wxPythonによるイベント処理が上手くいきません教えて下さい

bellarcnus

総合スコア15

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/01/14 16:50

今、Pythonでファイルをファイルの生データを選択して処理した結果を表示するGUIのプログラムを書いているのですが、上手くいかないので教えてください。
GUIにはwxPythonを使用しています。処理はできているのですがその結果を上手くGUIのウィンドウにもっていくことができません。ファイルを選択してから表示したいグラフをウィンドウの方のボタンを押すことで表示したいのですが、表示されずに止まってしまいます。

上手くいかないのはCalss以降なのですが、最初はbuttonのイベントにグラフを表示するイベントを入れれば表示されると思っていたのですが、止まってしまい。ウィンドウにグラフを表示する場所を指定していなかったからかと思いやってみたのですが、動かず。それはグラフを表示するキャンバスのエラーだったので、最初に空のFigureを入れとけば、イベント実行後切り替わるかと思ったのですが、止まってしまいました。修正点を教えてください。

そもそも何がいけないのかよくわかっていないので、そこらへんから教えていただけるとありがたいです。

Python3.7

1from mpl_toolkits.mplot3d import Axes3D 2import numpy as np 3import csv 4import matplotlib.pyplot as plt 5from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg 6import copy 7import wx 8%matplotlib notebook 9 10#ファイル選択ダイアログ+解析の処理がありますが、長くなる+研究なので割愛 11 12def plot_2D(): 13 global fig_2D 14 fig_2D = plt.figure() 15 plt.plot(x_axis,plot[1]) 16 17def plot_3D(): 18 global fig_3D 19 fig_3D = plt.figure() 20 ax = Axes3D(fig_3D) 21 color3d = ax.plot_surface(X, Y, Z_np, cmap='hot') 22 23def plot_2D_color(): 24 global fig_2D_color 25 fig_2D_color = plt.figure() 26 color2d = plt.pcolormesh(X, Y, Z_np, cmap='hot') 27 28class CustomFrame(wx.Frame): 29 30 def __init__(self,title): 31 wx.Frame.__init__(self,None,-1,title,size=(1200,800)) 32 33 def click_open(event): 34 #ファイル選択+前処理 35 open_file() 36 plot_2D_color() 37 38 def click_2D(event): 39 plot_2D() 40 41 def click_3D(event): 42 plot_3D() 43 44 self.panel = wx.Panel(self) 45 46 self.panel_1 = wx.Panel(self.panel,wx.ID_ANY) 47 self.panel_2 = wx.Panel(self.panel,wx.ID_ANY) 48 49 self.panel_1.SetBackgroundColour('#FCF8F0') 50 self.panel_2.SetBackgroundColour('#FC4000') 51 self.panel.SetBackgroundColour('#C70230') 52 53 layout = wx.BoxSizer(wx.VERTICAL) 54 layout.Add(self.panel_1, flag=wx.EXPAND) 55 layout.Add(self.panel_2, flag=wx.EXPAND) 56 self.panel.SetSizer(layout) 57 58 Butt_1 = wx.Button(self.panel_1,wx.ID_ANY,'開く') 59 Butt_2 = wx.Button(self.panel_1,wx.ID_ANY,'2D断面') 60 Butt_3 = wx.Button(self.panel_1,wx.ID_ANY,'3D形状') 61 62 Butt_1.Bind(wx.EVT_BUTTON, click_open) 63 Butt_2.Bind(wx.EVT_BUTTON, click_2D) 64 Butt_3.Bind(wx.EVT_BUTTON, click_3D) 65 66 layout_Butt = wx.BoxSizer(wx.HORIZONTAL) 67 layout_Butt.Add(Butt_1) 68 layout_Butt.Add(Butt_2) 69 layout_Butt.Add(Butt_3) 70 self.panel_1.SetSizer(layout_Butt) 71 72 fig_2D_color = plt.figure() 73 fig_2D = plt.figure() 74 fig_3D = plt.figure() 75 76 self.canvas_1 = FigureCanvasWxAgg(self.panel_2, wx.ID_ANY, fig_2D_color) 77 self.canvas_2 = FigureCanvasWxAgg(self.panel_2, wx.ID_ANY, fig_2D) 78 self.canvas_3 = FigureCanvasWxAgg(self.panel_2, wx.ID_ANY, fig_3D) 79 80 layout_Panel = wx.BoxSizer(wx.HORIZONTAL) 81 layout_Panel.Add(self.canvas_1) 82 layout_Panel.Add(self.canvas_2) 83 layout_Panel.Add(self.canvas_3) 84 self.panel_2.SetSizer(layout_Panel) 85 86 plt.show() 87 88 89 self.Show() 90 91app = wx.App() 92CustomFrame('AFM') 93app.MainLoop()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

wxPython/Jupyterに暗く、完全には動かなかったのですが、気づいた点をコメントしてみます。間違いがあるかも知れません。指摘などいただければありがたいです。

(多分)matplotlib.pyplotは使ってはいけない

これを下手に使うとmatplotlib自信がウィンドウを生成してしまうようです。このプログラムはウィンドウの制御にwxPythonを使うわけですからpyplotはimport自体をやめたほうがよいでしょう。
またplt.show()なんてのも不要です。そのあたりもwxPythonの方が制御を支配しますので。

よってplt.figure()ではなくfrom matplotlib.figure import Figureとした上でfig = Figure(None)で生成するとよいでしょう。

オブジェクト指向的(?)なmatplotlibの使い方を理解する

pyplotが使えないので、matplotlibの制御は全てFigure/Axes(クラス名はxxSubplotだったりする?)へのメソッド呼び出しにしなければならないと思います。matplotlib単体で以下のように書ける練習をしておいた方がよいでしょう。

Python

1import matplotlib.pyplot as plt 2 3plt.plot(...) 4plt.subplot(111) # これは現在のFigureの現在のAxesに対する描画であることを理解しておく 5plt.xlim(...) # 同上 6plt.xticks(...) # 同上 7... 8 9# ↑のような書き方を封印し 10# ↓のように書く練習をしておく。 11 12fig = plt.figure() # wxPythonを使わない場合の記述です。念のため 13ax = fig.add_subplot(111) 14ax.plot(...) 15ax.set_xlim(...) 16ax.set_xticks(...) 17...

描画したらFigureCanvasWxAggのdrawメソッドを呼ぶ(推測)

単にmplのAxesへグラフを描画してもFigureCanvasWxAgg上には反映されないみたいです。Axesへグラフを描画した後でFigureCanvasWxAgg.draw()を呼び出すと反映されました。

わからなかった点

CPython環境で以下のような簡単な画面は出せたのですが・・・

Python

1import wx 2from wx import (Frame, Panel, BoxSizer, Button, 3 ID_ANY, VERTICAL, EVT_BUTTON) 4 5import matplotlib as mpl 6mpl.interactive(True) 7mpl.use('WxAgg') 8 9from matplotlib.figure import Figure 10from mpl_toolkits.mplot3d import Axes3D 11from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg 12import numpy as np 13 14 15class MyFrame(Frame): 16 def __init__(self, title): 17 super().__init__(None, ID_ANY, title, size=(300, 300)) 18 19 self.panel = Panel(self) 20 layout = BoxSizer(VERTICAL) 21 self.panel.SetSizer(layout) 22 23 button = Button(self.panel, ID_ANY, 'plot') 24 layout.Add(button) 25 button.Bind(EVT_BUTTON, self.on_click) 26 27 self.fig = Figure(None) 28 self.ax = Axes3D(self.fig) 29 self.canvas = FigureCanvasWxAgg(self.panel, ID_ANY, self.fig) 30 layout.Add(self.canvas) 31 32 self.Show() 33 34 def on_click(self, ev): 35 print('2D color') 36 x = np.arange(-3, 3, 0.25) 37 x, y = np.meshgrid(x, x) 38 z = np.sin(x) + np.cos(y) 39 self.ax.plot_wireframe(x, y, z) 40 self.canvas.draw() 41 42 43def main(): 44 app = wx.App() 45 fr = MyFrame('wx test') 46 app.MainLoop() 47 print('app stop') 48 49 50if __name__ == '__main__': 51 main()

%matplotlib notebook
とする以上matplotlibのバックエンドはJupyter Notebookでなければならないはずで、そこにwxPythonが入り込む余地がない気がするのですが・・・

上記のコードのまま動かすとNotebookのインラインとしては何も表示されずCPython環境でのようにブラウザーとは別のウィンドウ(wxPythonのウィンドウ)が表示されましたが、これは質問者さんの意図とは別物だと思います。それともJupyterでwxPythonを使えるのでしょうか・・・?

https://qiita.com/tausho/items/2fdb35e5b9aa3bebd526
こういう記事をみるとNotebookと独立なウィンドウが出てますよね・・・これでいいならわざわざNotebook上で動かさなくていい気がしました。

このあたりが自分にわからなかった点です。


追記1: ゆくゆくはスタンドアロンGUIアプリケーションにしたいとのこと。前の質問でhayataka2049さんが言っておられることに関連しますが、もしスタンドアロンGUIアプリを目指すなら

(1) Notebookで実行するのは止した方がいいと思います。
回答と同じコードをCPython, Notebookで動かしたとき異なる動作となるからです。CPythonだとwxPythonのウィンドウ上で3Dグラフをマウス操作できますがNotebookだとそれができません。この問題はSpyder, QtConsoleでも同様に発生することからAnaconda環境とCPython環境の違いによるものなのかも知れません。

(2) Nodebook固有の記述をソースに入れるのは止した方がいいと思います。
本来の動作環境がNotebookでないなら%matplotlib ...の行)は書かないほうがよいと思います。それがコード中にあると閲覧者が「あなたの狙いはNotebook前提のプログラム」と誤解するからです。

投稿2019/01/15 05:08

編集2019/01/15 14:56
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bellarcnus

2019/01/15 12:51 編集

丁寧な回答ありがとうございます。matplotlibの方については確認勉強中ですが、先に最後のわからなかった点についてなのですが ご想像の通り一つのguiウィンドウにグラフを複数もしくは切り替えて表示したいです。jupyter notebook上でのグラフ表示はできるのですが、最終的には研究室のpythonを使えない方にも簡単に使えるようにexeしたいのです。また、グラフもまだ3枚程度しかないですが、最終的には数十枚のグラフを扱うのでそのたびに新しいウィンドウ出てくるのではなくguiのウィンドウ上で切り替わる方見やすいと思いwxpythonを使用しています。
KSwordOfHaste

2019/01/15 14:56 編集

なるほどNotebookが前提というわけではないのですね... 前の質問を今見たのですが、質問者さんの状況がなんとなくわかりました。うーん別のアドバイスもあったほうが良いかも知れません。 --- 「別のアドバイス」を回答に追記しました。
bellarcnus

2019/01/15 15:32

以前の質問まで見ていただき、ありがとうございます。Anaconda環境しか使ったことがなかったのですが、他のを使った方がいいということでしょうか。環境の違いなどについてはよくわかっていないのですが、おすすめ、もしくは詳しく説明している本やサイトなどあれば教えてほしいです。 また、Pythonを入れていない人にも使えるようにするのが目的なのでGUIではなくても構わないのですが、何かいい方法があれば教えていただきたいです。
KSwordOfHaste

2019/01/15 16:56

>他のを使ったほうがいいか? 端的に言えば「CPython + PyCharm」が自分にとってのベストだと考えていますが、それを単純に一般の人にお勧めできるかといえば微妙です。CPython+PyCharmは非常によい点もあれば難しい点もあるのです。難しい点は環境設定などですが、自分に取ってその難しさは克服すべきものと考えているため問題になりません。しかし前提知識・問題解決スキル・使える時間など事情が異なる他者に対して単純によいと安易に言えないのです。 それについて知るには、まずご自分でできる限り調べ、選択に関して関係しそうな条件(前提知識・スキル・どこまで学習時間が許容できるか等々)をできる限り整理して質問するとよいかも知れません。
bellarcnus

2019/01/16 06:28

一度、CPythonやPyCharmについて調べてみようと思います。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問