|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
先说情况:
再把sympy装进matplatlib,再开一个条形窗口放按钮(至于这么干有啥意义,不是讨论的内容)
就是这样的效果,参考的东西太多了,七拼八凑搞起来的(问题求助就贴就不列举感谢网址了)
点击matplotlib下的按钮可以变化左边条形图的表示内容,准备了4个样本
右边点击图形表示,可以变变化右上窗口的表示内容(实际有问题,因为调用走一个调用matplotlib,再调用sympy的过程,途中有隐含窗体被创建,代码中努力消去这个窗口,执行20多次,还是会出窗体数量超标的警告),这个数据也准备了4个图形函数样本。左边matplotlib的话,只是单纯,数据清空,再填入,再表示,按多少次都没有问题。希望的是,右边按钮和左边同样,无论按多少次都不会处警告
为啥要加sympy呢,主要是他有隐函数模拟比如:x**2+y**2-5=0,这是一个圆方程,但是如果复杂的话,很难转成y=f(x)这样的形式,这个比较牛,所以想把他装进来。另外刷新,是因为想可以手动输入方程,然后点图形显示(实际它有许多方程的表示法,这个隐方程的网上例子太少了,连他官网也没啥例子,更不用说怎么装到matplotlib,还要提供按键接受输入框输入的方程,所以这个没有实现,只是用了plot_parametric(cos(x), sin(x), (x, 0, 2*pi), show=False)这样的方程形式)。关闭窗口还是要按“关闭”按钮,因为里面执行了代码“plt.close('all')”,会关闭所有窗体(包括隐含的),直接按windows的“×”可能会内存泄漏。。。
想法源于:数学之美——你见过哪些优美的数学方程曲线?
这里面:极坐标r=f(θ)可能没问题,有些类似:(x^2+y^2-1)^2=x^3,好像没法解,当然可以区域模拟:给范围,用足够小的分辨率,一个坐标一个坐标模拟,然后结果是等式两边相减接近0。不过想到python有许多库,不用自己做,果然找到了sympy,然后想把sympy装到thinker,没有直接装的例子,无从下手,找到sympy装到matplatlib例子,然后matplatlib装入thinker官网就有例子的,再就是既然装了两个,再加一个按钮条,加了按钮条总不能什么都不做,就想要上边两个窗体的刷新(数据都列举在代码中了,可以直接运行的,右边按钮点30次一定会出窗体数超标吧。。。):
- import tkinter as tk
- from tkinter import *
- from pandas import DataFrame
- import matplotlib.pyplot as plt
- from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
- from sympy.plotting.plot import plot_parametric
- import sympy.geometry.util
- from sympy import *
- from sympy.abc import x,y,z
- from sympy import plot_implicit
- #ezplot = lambda exper: plot_implicit(parse_expr(exper))#用了匿名函数
- class App:
- data1 = [{'Country': ['US','CA','GER','UK','FR'],
- 'GDP_Per_Capita': [45000,42000,52000,49000,47000]
- },
- {'Country': ['US','CA','GER','UK','FR'],
- 'GDP_Per_Capita': [35000,42000,50000,43000,52000]
- },
- {'Country': ['US','CA','GER','UK','FR'],
- 'GDP_Per_Capita': [42000,52000,49000,47000,45000]
- },
- {'Country': ['US','CA','GER','UK','FR'],
- 'GDP_Per_Capita': [52000,49000,47000,45000,42000]
- }]
- data1_ptr = 0
- line2_ptr = 0
-
- def __init__(self):
- #------------------------------------------------
- #tkinter 画面划分
- #------------------------------------------------
- root= tk.Tk()
- root.resizable(0,0)
- embed = tk.Frame(root, width = 1100, height = 550) #creates embed frame for pygame window
- embed.grid(columnspan = (1100), rowspan = 500) # Adds grid
- embed.pack(side = TOP) #packs window to the left
- buttonwin = tk.Frame(root, width = 1100, height = 50)
- buttonwin.pack(side = BOTTOM)
- #------------------------------------------------
- #
- #------------------------------------------------
-
- #控件定义区 =====================================
- button_mat_b = Button(buttonwin,text = 'matlab再表示', width=11, command=self.show_mat)
- button_mat_b.place(x=200,y=0)
- btnwin_fl_l = tk.Label(buttonwin, text='式子:')
- btnwin_fl_l.place(x=300,y=5)
- inputfl = StringVar()
- btnwin_fl_e = tk.Entry(buttonwin, width=70,textvariable = inputfl)
- btnwin_fl_e.place(x=350,y=5)
- button_show_b = Button(buttonwin,text = '图形表示', width=11, command=self.show_fl)
- button_show_b.place(x=850,y=0)
- button_show_b = Button(buttonwin,text = '关闭窗口', width=11, command=self.exit)
- button_show_b.place(x=1000,y=0)
-
- #matplotlib,matplotlib内嵌sympy子窗体
- figure1 = plt.Figure(figsize=(6,5), dpi=100)
- ax1 = figure1.add_subplot(111)
- bar1 = FigureCanvasTkAgg(figure1, embed)
- bar1.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH)
- df1 = DataFrame(App.data1[0],columns=['Country','GDP_Per_Capita'])
- df1 = df1[['Country','GDP_Per_Capita']].groupby('Country').sum()
- df1.plot(kind='bar', legend=True, ax=ax1)
- ax1.set_title('Country Vs. GDP Per Capita')
- figure2 = plt.Figure(figsize=(5,4), dpi=100)
- p2 = self.get_plot_parametric()
- ax2 = figure2.add_subplot(111)
- self.move_sympyplot_to_axes(p2, ax2)
- line2 = FigureCanvasTkAgg(figure2, embed)
- line2.get_tk_widget().pack(side=tk.RIGHT, fill=tk.BOTH)
-
- #---------------------------- 对外接口
- App.root = root
- App.bar1 = bar1
- App.figure1 = figure1
- App.ax1 = ax1
- App.figure2 = figure2
- App.line2 = line2
- App.ax2 = ax2
-
- #按钮动作区 =====================================
- def exit(self):
- plt.close('all')
- App.root.quit() # stops mainloop
- App.root.destroy() # this is necessary on Windows to prevent
-
- def show_mat(self):
- App.data1_ptr = (App.data1_ptr+1)%4
- App.figure1.clear()
- App.ax1.clear()
- App.ax1 = App.figure1.add_subplot(111)
- App.df1 = DataFrame(App.data1[App.data1_ptr],columns=['Country','GDP_Per_Capita'])
- App.df1 = App.df1[['Country','GDP_Per_Capita']].groupby('Country').sum()
- App.df1.plot(kind='bar', legend=True, ax=App.ax1)
- App.ax1.set_title('Country Vs. GDP Per Capita')
- App.bar1.draw()
-
- def get_plot_parametric(self):
- App.line2_ptr = (App.line2_ptr+1) % 4
- if App.line2_ptr == 0:
- return plot_parametric(cos(x), sin(x), (x, 0, 2*pi), show=False)
- elif App.line2_ptr == 1:
- return plot_parametric(cos(x), x, (x, 0, 2*pi), show=False)
- elif App.line2_ptr == 2:
- return plot_parametric(cos(x), cos(x), (x, -5, 5), show=False)
- else:
- return plot_parametric(2*x, sin(x), (x, 0, 2*pi), show=False)
- def show_fl(self):
- App.figure2.clear()
- App.p2 = self.get_plot_parametric()
- App.ax2 = App.figure2.add_subplot(111)
- self.move_sympyplot_to_axes(App.p2, App.ax2)
- App.line2.draw()
- def move_sympyplot_to_axes(self,p, ax):
- backend = p.backend(p)
- backend.ax = ax
- # Fix for > sympy v1.5
- backend._process_series(backend.parent._series, ax, backend.parent)
- backend.ax.spines['right'].set_color('none')
- backend.ax.spines['bottom'].set_position('zero')
- backend.ax.spines['top'].set_color('none')
- #plt.close(backend.fig)
- plt.close(plt.figure())
-
- App().root.mainloop()
复制代码 |
|