鱼C论坛

 找回密码
 立即注册
查看: 1281|回复: 1

把sympy装入matplatlib再装进thinker后的问题

[复制链接]
发表于 2020-6-25 10:29:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
先说情况:
再把sympy装进matplatlib,再开一个条形窗口放按钮(至于这么干有啥意义,不是讨论的内容)
thinker_matplatlib_sympy.jpg
就是这样的效果,参考的东西太多了,七拼八凑搞起来的(问题求助就贴就不列举感谢网址了)
点击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次一定会出窗体数超标吧。。。):
  1. import tkinter as tk
  2. from tkinter import *
  3. from pandas import DataFrame
  4. import matplotlib.pyplot as plt
  5. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
  6. from sympy.plotting.plot import plot_parametric
  7. import sympy.geometry.util
  8. from sympy import *
  9. from sympy.abc import x,y,z
  10. from sympy import plot_implicit
  11. #ezplot = lambda exper: plot_implicit(parse_expr(exper))#用了匿名函数

  12. class App:
  13.     data1 = [{'Country': ['US','CA','GER','UK','FR'],
  14.              'GDP_Per_Capita': [45000,42000,52000,49000,47000]
  15.             },
  16.             {'Country': ['US','CA','GER','UK','FR'],
  17.              'GDP_Per_Capita': [35000,42000,50000,43000,52000]
  18.             },
  19.             {'Country': ['US','CA','GER','UK','FR'],
  20.              'GDP_Per_Capita': [42000,52000,49000,47000,45000]
  21.             },
  22.             {'Country': ['US','CA','GER','UK','FR'],
  23.              'GDP_Per_Capita': [52000,49000,47000,45000,42000]
  24.             }]
  25.     data1_ptr  = 0
  26.     line2_ptr  = 0
  27.    
  28.     def __init__(self):
  29.         #------------------------------------------------
  30.         #tkinter 画面划分
  31.         #------------------------------------------------
  32.         root= tk.Tk()
  33.         root.resizable(0,0)

  34.         embed = tk.Frame(root, width = 1100, height = 550) #creates embed frame for pygame window
  35.         embed.grid(columnspan = (1100), rowspan = 500) # Adds grid
  36.         embed.pack(side = TOP) #packs window to the left

  37.         buttonwin = tk.Frame(root, width = 1100, height = 50)
  38.         buttonwin.pack(side = BOTTOM)
  39.         #------------------------------------------------
  40.         #
  41.         #------------------------------------------------
  42.         
  43.         #控件定义区 =====================================
  44.         button_mat_b = Button(buttonwin,text = 'matlab再表示', width=11, command=self.show_mat)
  45.         button_mat_b.place(x=200,y=0)

  46.         btnwin_fl_l = tk.Label(buttonwin, text='式子:')
  47.         btnwin_fl_l.place(x=300,y=5)
  48.         inputfl = StringVar()
  49.         btnwin_fl_e = tk.Entry(buttonwin, width=70,textvariable = inputfl)
  50.         btnwin_fl_e.place(x=350,y=5)
  51.         button_show_b = Button(buttonwin,text = '图形表示', width=11, command=self.show_fl)
  52.         button_show_b.place(x=850,y=0)
  53.         button_show_b = Button(buttonwin,text = '关闭窗口', width=11, command=self.exit)
  54.         button_show_b.place(x=1000,y=0)
  55.         
  56.         #matplotlib,matplotlib内嵌sympy子窗体
  57.         figure1 = plt.Figure(figsize=(6,5), dpi=100)
  58.         ax1 = figure1.add_subplot(111)
  59.         bar1 = FigureCanvasTkAgg(figure1, embed)
  60.         bar1.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH)
  61.         df1 = DataFrame(App.data1[0],columns=['Country','GDP_Per_Capita'])
  62.         df1 = df1[['Country','GDP_Per_Capita']].groupby('Country').sum()
  63.         df1.plot(kind='bar', legend=True, ax=ax1)
  64.         ax1.set_title('Country Vs. GDP Per Capita')

  65.         figure2 = plt.Figure(figsize=(5,4), dpi=100)
  66.         p2 = self.get_plot_parametric()
  67.         ax2 = figure2.add_subplot(111)
  68.         self.move_sympyplot_to_axes(p2, ax2)
  69.         line2 = FigureCanvasTkAgg(figure2, embed)
  70.         line2.get_tk_widget().pack(side=tk.RIGHT, fill=tk.BOTH)
  71.         
  72.         #---------------------------- 对外接口
  73.         App.root       = root
  74.         App.bar1       = bar1
  75.         App.figure1    = figure1
  76.         App.ax1        = ax1
  77.         App.figure2    = figure2
  78.         App.line2      = line2
  79.         App.ax2        = ax2
  80.         
  81.     #按钮动作区 =====================================
  82.     def exit(self):
  83.         plt.close('all')
  84.         App.root.quit()     # stops mainloop
  85.         App.root.destroy()  # this is necessary on Windows to prevent
  86.         
  87.     def show_mat(self):
  88.         App.data1_ptr = (App.data1_ptr+1)%4
  89.         App.figure1.clear()
  90.         App.ax1.clear()
  91.         App.ax1 = App.figure1.add_subplot(111)
  92.         App.df1 = DataFrame(App.data1[App.data1_ptr],columns=['Country','GDP_Per_Capita'])
  93.         App.df1 = App.df1[['Country','GDP_Per_Capita']].groupby('Country').sum()
  94.         App.df1.plot(kind='bar', legend=True, ax=App.ax1)
  95.         App.ax1.set_title('Country Vs. GDP Per Capita')
  96.         App.bar1.draw()
  97.         
  98.     def get_plot_parametric(self):
  99.         App.line2_ptr = (App.line2_ptr+1) % 4
  100.         if App.line2_ptr == 0:
  101.             return plot_parametric(cos(x), sin(x), (x, 0, 2*pi), show=False)
  102.         elif App.line2_ptr == 1:
  103.             return plot_parametric(cos(x), x, (x, 0, 2*pi), show=False)
  104.         elif App.line2_ptr == 2:
  105.             return plot_parametric(cos(x), cos(x), (x, -5, 5), show=False)
  106.         else:
  107.             return plot_parametric(2*x, sin(x), (x, 0, 2*pi), show=False)

  108.     def show_fl(self):
  109.         App.figure2.clear()
  110.         App.p2 = self.get_plot_parametric()
  111.         App.ax2 = App.figure2.add_subplot(111)
  112.         self.move_sympyplot_to_axes(App.p2, App.ax2)
  113.         App.line2.draw()

  114.     def move_sympyplot_to_axes(self,p, ax):
  115.         backend = p.backend(p)
  116.         backend.ax = ax
  117.         # Fix for > sympy v1.5
  118.         backend._process_series(backend.parent._series, ax, backend.parent)
  119.         backend.ax.spines['right'].set_color('none')
  120.         backend.ax.spines['bottom'].set_position('zero')
  121.         backend.ax.spines['top'].set_color('none')
  122.         #plt.close(backend.fig)
  123.         plt.close(plt.figure())
  124.         
  125. App().root.mainloop()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-6-25 18:20:12 | 显示全部楼层
顶上去,审核了帖子沉了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-22 18:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表