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

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

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

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

Python

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

Q&A

解決済

2回答

2188閲覧

python tkinterを使用してボタンでイベントを発生させたい

kzi98

総合スコア2

Matplotlib

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

Python

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

0グッド

0クリップ

投稿2020/08/19 05:59

前提・実現したいこと

matplolibで作成した、色と形をランダムに表示するというプログラムを、tkinter上で、ボタンを押す操作をすることより繰り返し表示させたいと考えています。
ですが、matplotlibとtkinterの紐づけ方がわからずに困っております。

全体的なプログラムの構造としては、def draw()内に、ボタンを押すごとに実行したいプログラムを貼り付け、そしてbutton.bind("<Button-1>",draw)で繰り返そうとしています。
def draw内のプログラムの内容は、実行するごとに色がRGB表色系でランダムに選ばれ、形は新月~新月までの月の形をランダムに表すものとしました。
有識者の方、どうかご教示お願いいたします。

発生している問題・エラーメッセージ

TypeError: draw() takes 0 positional arguments but 1 was given

該当のソースコード

Python

1import sys 2import tkinter 3import numpy as np 4import random 5import matplotlib.pyplot as plt 6from mpl_toolkits.mplot3d import Axes3D 7from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) 8from matplotlib.figure import Figure 9 10 11def draw(): 12 fig = plt.figure(figsize=(10,10)) 13 ax=fig.gca(projection='3d') 14 ax.set_xlim([-1., 1.]) 15 ax.set_ylim([-1., 1.]) 16 ax.set_zlim([-1., 1.]) 17 for a in [ax.xaxis, ax.yaxis, ax.zaxis]: 18 a.set_ticklabels([]) 19 a._axinfo['grid']['linewidth'] = 0 20 a._axinfo['tick']['linewidth'] = 0 21 22 for a in [ax.w_xaxis, ax.w_yaxis, ax.w_zaxis]: 23 a.line.set_linewidth(0) 24 a.set_pane_color((0., 0., 0., 0.)) 25 #順にRGBA 26 27 ax.set_facecolor('black') 28 29 30 u, v = np.mgrid[0:2*np.pi:50j, 0:np.pi:25j] 31 32 x = np.cos(u) * np.sin(v) 33 y = np.sin(u) * np.sin(v) 34 z = np.cos(v) 35 36 a=random.random() 37 b=random.random() 38 c=random.random() 39 40 colors = np.zeros((50, 25, 3)) 41 for i in range(0, 25): 42 for j in range(0, 25): 43 colors[i][j][0] = a 44 colors[i][j][1] = b 45 colors[i][j][2] = c 46 47 ax.plot_surface(x, y, z, facecolors = colors, shade = False) 48 49 moon=random.randint(-90,270) 50 51 ax.view_init(elev = 0, azim = moon) 52 53 canvas = tkinter.Canvas(root, width = 800, height = 300) 54 canvas.draw() 55 canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) 56 57root = tkinter.Tk() 58root.wm_title("色と形をランダムに表示する") 59 60button= tkinter.Button(root, text=u'かく',width=15) 61button.bind("<Button-1>",draw) 62button.place(x=200,y=350) 63 64tkinter.mainloop()

試したこと

エラーメッセージで引数がないと言われたので、selfを入れてみましたが解決に至りませんでした

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

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

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

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

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

guest

回答2

0

気になる点としては三点程です。
まず一点目で質問に記述されている、発生しているエラーメッセージの部分ですが、
bindでイベントを設定した場合は呼び出される関数側にeventを取る引数が要ります。
それがないためにエラーとなっていますので取るためのなんらかの変数を設定してください。

python

1・・・ 2def draw(e): 3・・・

次に二点目ですが、枠の大きさを設定していないため、
かなり狭くボタンが完全に枠外になっていて押せません。
ひとまず暫定で設定させてもらいました。

python

1・・・ 2root = tkinter.Tk() 3root.geometry("800x600") 4root.wm_title("色と形をランダムに表示する") 5・・・

最後に三点目ですが、draw関数の最後の方でcanvas変数にCanvasを設定されていますが、
続く部分で使っている関数を見る限り、
これはFigureCanvasTkAggの間違いだと思います。

python

1・・・ 2def draw(e): 3・・・ 4 canvas = FigureCanvasTkAgg(fig, master=root) 5 canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) 6 canvas.draw() 7・・・

こうすることでmatplotlibで生成した内容が書き出されます。

質問者が想定されているものかはわかりませんが、
上記三点を修正すれば一先ずエラーが出ずにmatplotlibの内容が書き出されます。

投稿2020/08/19 06:52

yureighost

総合スコア2183

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

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

kzi98

2020/08/19 07:43 編集

ご回答ありがとうございます。 三点目の内容に関して質問があります。 canvas.draw()がない場合でも、ある場合と同じように動作したのですが、この一文はどのようにプログラムに関わっているのでしょうか。 初歩的な質問で申し訳ございませんが、よろしくお願いいたします。
yureighost

2020/08/19 08:13

FigureCanvasTkAggに渡したオブジェクトの値を変更して 再描画したい場合にはdraw関数で書き出す必要があるようです。 サンプルはcan110さんが追記して下さった物が最適かと思います。
kzi98

2020/08/19 11:16 編集

そういうことなのですね…ありがとうございます。勉強になりました。 恐縮ですがベストアンサーは先に回答くださったcan110さんをベストアンサーとさせて頂きました。 大変わかりやすく教えてくださり、ありがとうございました。
guest

0

ベストアンサー

まずdef draw():def draw(event):と引数eventを受けるようにします。
さらに

Python

1 fig = plt.figure(figsize=(1,1)) # 小さく 2 3 #canvas = tkinter.Canvas(root, width = 800, height = 300) 4 #canvas.draw() 5 #canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) 6 canvas = FigureCanvasTkAgg(fig, master=root) 7 canvas.get_tk_widget().place(x=0,y=0) # そのままの大きさで配置

のように書き換えると、とりあえず動作するようになります。
元のソースでは画像にボタンがかぶってしまうのでご自身で調整ください。

追記

シンプルなサンプルを以下に示します。

Python

1import tkinter 2import matplotlib.pyplot as plt 3from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 4import numpy as np 5import random 6 7def draw(e): 8 ax.cla() 9 xy = np.random.random(size=(10,2)) 10 ax.scatter(xy[:,0],xy[:,1]) 11 canvas.draw() 12 13root = tkinter.Tk() 14fig, ax = plt.subplots() 15canvas = FigureCanvasTkAgg( fig, master=root) 16canvas.get_tk_widget().pack() 17btn = tkinter.Button(text='draw') 18btn.bind('<Button-1>', draw) 19btn.pack() 20 21draw() 22root.mainloop()

投稿2020/08/19 06:41

編集2020/08/19 07:34
can110

総合スコア38341

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

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

kzi98

2020/08/19 07:44 編集

大変勉強になりました。 教えて頂きました通りに実装すると無事プログラムを動かすことできました。 ご回答ありがとうございました。
kzi98

2020/08/19 07:52

追記拝見しました。ありがとうございます。 知識不足であると感じたのでシンプルなものから学んでいこうと思います。 追記を参考にさせて頂き、勉強します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問