鱼C论坛

 找回密码
 立即注册
查看: 1055|回复: 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次一定会出窗体数超标吧。。。):
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()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-6-25 18:20:12 | 显示全部楼层
顶上去,审核了帖子沉了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-20 10:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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