update FunctionDisplay file code

master
bettleChen 1 year ago
parent cc574d0422
commit 4863ecd1db

@ -1,404 +0,0 @@
import random
import math
import numpy as np
import tkinter as tk
from math import *
from tkinter import *
from tkinter import messagebox
import matplotlib.pyplot as plt
import numpy.ma
import pyautogui as ag
from numpy import arange
def leftclick(event): # 测试鼠标点击
x, y = event.x, event.y
print('坐标{}, {}'.format(x, y))
def window_open(width, height):
X, Y = ag.size() # 获取分辨率
winSize = str(width) + "x" + str(height)
# print("winsize",winSize)
wiarangeos = winSize + "+" + str((X - width) // 2)
wiarangeos += "+" + str((Y - height) // 2)
# print("wiarangeos",wiarangeos)
# window.geometry(wiarangeos) #指定窗口大小
# window.resizable(False, False) #窗口不可调
title = u'桌面分辨率:' + str(X) + "x" + str(Y)
title += ' ' * 5 + u'窗体大小:' + winSize
window.title(title)
# window.update()
def x1_1(): # 随机给出1000个点坐标,赋值给xyMap,<class 'numpy.ndarray'>
shape = [1000, 2]
xyMap = np.random.randint(-200, 200, size=shape)
return xyMap
print(x1_1())
# ab = x1_1()
# print(ab,len(ab),type(ab))
def x1_2(problemIndex): # 程序给出任一函数 y=f(x)计算x=1到1000的y值赋值给xyMap
# shape = [1000,2] #x值为1到1000y为其对应函数值
xyMap = np.random.rand(1000, 2)
if problemIndex == 1:
for x in range(1, 1001):
xyMap[x - 1][0] = x # xyMap序号为0-999
xyMap[x - 1][1] = np.sin(x)
return xyMap
elif problemIndex == 2:
for x in range(1, 1001):
xyMap[x - 1][0] = x
xyMap[x - 1][1] = np.cos(x)
return xyMap
elif problemIndex == 3:
for x in range(1, 1001):
xyMap[x - 1][0] = x
xyMap[x - 1][1] = np.tan(x)
return xyMap
elif problemIndex == 4:
for x in range(1, 1001):
xyMap[x - 1][0] = x
xyMap[x - 1][1] = x * 2 + 2
return xyMap
print(x1_2(4)[:50])
print(x1_2(1))
def x1_3(problemIndex): # 程序给出任一函数y=f(x)计算x=-500到+500的y值赋值给xyMap
c = 0 # 此处x赋值为-500到-1到1到500到1000个
shape = [1000, 2] # y赋值为其对应的函数
xyMap = np.random.rand(1000, 2)
if problemIndex == 1:
for x in range(-500, 500):
if (x == 0):
continue
xyMap[c][0] = x
xyMap[c][1] = math.sin(x)
c += 1
return xyMap
elif problemIndex == 2:
for x in range(-500, 500):
if (x == 0):
continue
xyMap[c][0] = x
xyMap[c][1] = math.cos(x)
c += 1
return xyMap
elif problemIndex == 3:
for x in range(-500, 500):
if (x == 0):
continue
xyMap[c][0] = x
xyMap[c][1] = math.tan(x)
c += 1
return xyMap
elif problemIndex == 4:
for x in range(-500, 501):
if (x == 0):
continue
xyMap[c][0] = x
xyMap[c][1] = x * 2 + 2
c += 1
return xyMap
# print(x1_3(1))
def x1_4(ProblemIndex):
step = 3 # 步长
y = []
i, c = 0, 0
number = 1000 # 个数
while (True):
if (c == number):
break
else:
y.append(i)
i += step
c += 1
y = np.array(y)
xyMap = np.random.rand(1000, 2)
if (ProblemIndex == 1):
for i in range(len(y)):
xyMap[i][0] = y[i]
xyMap[i][1] = 2 * y[i] + 1
return xyMap
elif (ProblemIndex == 2):
for i in range(len(y)):
xyMap[i][0] = y[i]
xyMap[i][1] = y[i] / 3
return xyMap
def x_6(xymap): # 按xymap绘制曲线
xy = xymap.tolist()
canvas.create_line(xy, fill="purple", width=1)
def x_5(x, y):
# 1----x,y轴
canvas.create_line(0, y / 2, x, y / 2, fill='white', arrow=LAST) # 绘制x轴
canvas.create_line(x / 2, 0, x / 2, y, fill='white', arrow=FIRST) # 绘制y轴
# 绘制坐标轴的刻度
def kedu():
# #两个for分别为xy刻度
for i in range(-math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x - loca_y) / bili_x)):
j = i * bili_x
# i*bili_x即实际的坐标轴对应的放大bili倍后的值但是这个值并不是真正的像素点
# 以中心点(loca_y, loca_x)为原点的,要在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
if (i % 10 == 0):
canvas.create_line(j + loca_y, loca_x, j + loca_y, loca_x - 5, fill='black')
canvas.create_text(j + loca_y, loca_x + 10, text=i)
# y轴是相反的所以正半轴为cordinate_x负半轴为canvas_y - cordinate_x
# 此处的算法应该改为range*( -(canvas_y - loca_x) / bili_y) + 1, (cordinate_x / bili_y)) )
# xmin,xmax =math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x-loca_y) / bili_x)
# print(xmin,xmax)
for i in range(-math.ceil((canvas_y - loca_x) / bili_y) + 1, math.ceil((loca_x / bili_y))):
j = -(i * bili_y)
# i*bili_y即实际的坐标轴对应的放大bili倍后的值但是这个值并不是真正的像素点
# 以中心点(loca_y, loca_x)为原点的,因此在这里加上对应的原点像素值才能得到真正的坐标轴对应的像素点
if (i == 0):
continue
elif (i % 2 == 0):
canvas.create_line(loca_y, j + loca_x, loca_y + 5, j + loca_x, fill='black')
canvas.create_text(loca_y - 10, j + loca_x, text=i)
# print(loca_x,loca_y)
def si():
global x0, y0, loca_x, loca_y
x0, y0 = 375, 275 # 四象限原点坐标
loca_x, loca_y = y0, x0
canvas.create_rectangle(0, 0, x_zhou, y_zhou, fill='#CDCDCD', width=5, outline='#CDCDCD')
canvas.create_oval(170, y_zhou + 145, 200, y_zhou + 175, fill='black', width=1, outline='white')
canvas.create_oval(350, y_zhou + 145, 380, y_zhou + 175, fill='white', width=1, outline='black')
# kedu()
canvas.create_line(0, y0, x_zhou, y0, fill='white', arrow=LAST) # 一象限xy轴
canvas.create_line(x0, 0, x0, y_zhou, fill='white', arrow=FIRST)
def yi():
global x0, y0, loca_x, loca_y
x0, y0 = 20, 500 # 一象限原点
loca_x, loca_y = y0, x0
canvas.create_rectangle(0, 0, x_zhou, y_zhou, fill='#CDCDCD', width=5, outline='#CDCDCD')
canvas.create_oval(170, y_zhou + 145, 200, y_zhou + 175, fill='white', width=1, outline='black')
canvas.create_oval(350, y_zhou + 145, 380, y_zhou + 175, fill='black', width=1, outline='white')
# kedu()
canvas.create_line(0, y0, x_zhou, y0, fill='white', arrow=LAST) # 一象限xy轴
canvas.create_line(x0, 0, x0, y_zhou, fill='white', arrow=FIRST)
def x_show(x, y): # GUI界面 坐标系的x:x轴长yy轴长
xmin, xmax = math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x - loca_y) / bili_x)
# print("xmain",xmin,xmax)
# 1----x,y轴
# canvas.create_line(0,y0,x,y0,fill='white',arrow=LAST) # 一象限xy轴
# canvas.create_line(x0,0,x0,y,fill='white',arrow=FIRST)
# 2----背景涂白
canvas.create_rectangle(x, 0, 1200, y, fill='white', width=5, outline='white') # 右上区白色背景
canvas.create_rectangle(0, y, 1200, 800, fill='white', width=3, outline='white') # 下半区白色背景
# 3----输入框
e1 = tk.Entry(window, font=('Arial', 18), width=40, bg='#C0D9D9', bd=1) # 用户自命名函数输入
e1.place(x=70, y=y + 15, height=50)
canvas.create_text(95, y + 100, text="x步长", fill='black', font=("Purisa", 15, "bold"))
e2 = tk.Entry(window, font=('Arial', 15), width=15, bg='#C0D9D9', bd=1) # x步长输入
e2.place(x=130, y=y + 75, height=50)
canvas.create_text(380, y + 100, text="x个数", fill='black', font=("Purisa", 15, "bold"))
e3 = tk.Entry(window, font=('Arial', 15), width=15, bg='#C0D9D9', bd=1) # x个数输入
e3.place(x=415, y=y + 75, height=50)
e4 = tk.Entry(window, font=('Arial', 18), width=10, bg='#C0D9D9', bd=1) # x放大倍数
e4.place(x=200, y=750, height=35)
canvas.create_text(95, y + 100, text="x步长", fill='black', font=("Purisa", 15, "bold"))
e5 = tk.Entry(window, font=('Arial', 15), width=10, bg='#C0D9D9', bd=1) # y放大倍数
e5.place(x=580, y=750, height=35)
# 4----右侧label文本
canvas.create_text(x + 180, 35, text='可识别基本函数', fill='red', font=("Purisa", 25, "bold"))
text = "可支持下列函数的加减乘除组合运算\n" \
"y=sin(x)\n" \
"y=cos(x)\n" \
"y=tan(x)\n" \
"y=cot(x)\n" \
"y=x^n\n" \
"y=P1(y=x^3+x^2+x+5)\n" \
"---将括号内的表达式命名为P1,P1可\n" \
"出现于用户构造中"
label = tk.Label(window, text=text, font=('Arial', 15, 'bold italic'), bg='white',
# 设置标签内容区?
width=28, height=16,
# 设置填充区距离、边框宽度和其样式(凹陷式)
padx=5, pady=5, borderwidth=5, relief="sunken", justify="center")
label.place(x=x + 5, y=60)
# 5----左下按钮
canvas.create_text(100, y + 160, text="坐标轴", fill='black', font=("Purisa", 18, "bold"))
canvas.create_text(120, y + 210, text="x放大倍数", fill='black', font=("Purisa", 18, "bold"))
canvas.create_text(500, y + 210, text="y放大倍数", fill='black', font=("Purisa", 18, "bold"))
canvas.create_oval(170, y + 145, 200, y + 175, fill='white', width=1, outline='black') # 左小圆
canvas.create_oval(350, y + 145, 380, y + 175, fill='white', width=1, outline='black') # 右小圆
def function_user():
if (e1.get() == "y=sin(x)"):
Graph(0, sin, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#32CD32')
elif (e1.get() == "y=cos(x)"):
Graph(0, fx2, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#238E23')
elif (e1.get() == "y=tan(x)"):
Graph(0, fx3, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#FF6EC7')
elif (e1.get() == "y=cot(x)"):
Graph(0, fx4, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#CFB53B')
elif (e1.get() == "y=sin(x)+cos(x)"):
Graph(0, fx5, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#99CC32')
elif (e1.get() == "y=sin(x)*cos(x)"):
Graph(0, fx6, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
elif (e1.get() == "y=sin(x)-cos(x)+tan(x)"):
Graph(0, fx7, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
elif (e1.get() == "y=x"):
Graph(0, fx8, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
elif (e1.get() == "y=x**2"):
Graph(0, fx9, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
def function_print():
global bili_x, bili_y
bili_x = float(e4.get())
bili_y = float(e5.get())
buchang = float(e2.get())
kedu()
if (e1.get() == "y=sin(x)"):
Graph(buchang, sin, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#32CD32')
elif (e1.get() == "y=cos(x)"):
Graph(buchang, fx2, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#238E23')
elif (e1.get() == "y=tan(x)"):
Graph(buchang, fx3, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#FF6EC7')
elif (e1.get() == "y=cot(x)"):
Graph(buchang, fx4, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#CFB53B')
elif (e1.get() == "y=sin(x)+cos(x)"):
Graph(buchang, fx5, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#99CC32')
elif (e1.get() == "y=sin(x)*cos(x)"):
Graph(buchang, fx6, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
elif (e1.get() == "y=sin(x)-cos(x)+tan(x)"):
Graph(buchang, fx7, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#007FFF')
elif (e1.get() == "y=x"):
Graph(buchang, fx8, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
elif (e1.get() == "y=x**2"):
Graph(buchang, fx9, x0, y0, -xmin, xmax, 750 / 2, 300 / 2, c='#8E2323')
# 按钮一:命名函数
button = tk.Button(window, text='用户命名并新增基本函数', bg='#38B0DE', command=function_user,
font=("Purisa", 13, "bold"), foreground='black')
button.place(x=x + 8, y=y + 10, width=440, height=60)
# 按钮二:输出
button = tk.Button(window, text='输出', font=("Purisa", 13, "bold"), command=function_print, foreground='black')
button.place(x=x + 10, y=y + 90, width=70, height=60)
# 按钮三:切换四象限
button = tk.Button(window, command=si, text='四象限', bd=0, font=("Asria", 15, "bold"))
button.place(x=230, y=y + 140, width=70, height=45)
# 按钮四:切换一象限
button = tk.Button(window, command=yi, text='一象限', bd=0, font=("Asria", 15, "bold"))
button.place(x=400, y=y + 140, width=70, height=45)
def Graph(draw_precision, func, x0, y0, xmin, xmax, w, h, c='blue'): # 画基本函数图像
'xmin,xmax 自变量的取值范围; c 图像颜色'
'x0,y0 原点坐标 w,h 横纵轴半长 draw_precision 步进'
w1, w2 = bili_x, bili_y # w1,w2为自变量和函数值在横纵轴上的放大倍数
# w,h = 750/2,550/2
w, h = x_zhou, y_zhou
xmin, xmax = -math.ceil((loca_y / bili_x)) + 1, math.ceil((canvas_x - loca_y) / bili_x)
# xmax = math.ceil((canvas_x-loca_y) / bili_x)
co2 = []
count = 0
for x in arange(xmin, xmax, draw_precision): # draw_precision----画图精度
y = func(x)
# print(x,y)
# co2.append((x0+w1*x,y0-w2*y))
coord = x0 + w1 * x, y0 - w2 * y, x0 + w1 * x + 1, y0 - w2 * y + 1
# coord = x0+w1*x,y0-w2*y
# coord2 = x0+w1*x+1,y0-w2*y+1
# if abs(x*w1)<w and abs(y*w2)<h and abs(coord[1])<y_zhou:
if abs(coord[1]) < y_zhou: # 超过w,h就截断
# print(coord,type(coord))
co2.append((x0 + w1 * x, y0 - w2 * y))
# co2.append((x0+w1*x+draw_precision,y0-w2*y+draw_precision ))
# print(x,y)
# canvas.create_line(coord,coord2,fill=c,width=2)
for i in range(len(co2)):
if (draw_precision >= 1):
canvas.create_line(co2, fill=c, width=1)
if (i + 1 == len(co2)):
break
if (abs(co2[i][1] - co2[i + 1][1]) > 100):
continue
else:
canvas.create_line(co2[i], co2[i + 1], fill=c, width=1)
print("min,max:", xmin, xmax)
# print(co2,type(co2),len(co2)) #x个数
# canvas.create_line(co2,fill=c,width=1)
# canvas.create_line(co2[:20],fill=c,width=1)
canvas.update()
# y=tan(x)
# y=sin(x)
fx1 = lambda x: sin(x)
print(fx1)
fx2 = lambda x: cos(x)
fx3 = lambda x: tan(x)
fx4 = lambda x: (1 / tan(x)) # cot
fx5 = lambda x: sin(x) + cos(x)
fx6 = lambda x: sin(x) * cos(x)
fx7 = lambda x: sin(x) - cos(x) + tan(x)
fx8 = lambda x: x
fx9 = lambda x: (x ** 2)
width, height = 1200, 800 # 画布与窗口大小相同
x0, y0 = 375, 275 # 四象限原点坐标
# x0,y0 = 20,500 #一象限原点坐标
# xmin,xmax = 10,10 #自变量最大值
x_zhou, y_zhou = 750, 550
# canvas_x ,canvas_y = 800,480 #x,y轴长
canvas_x, canvas_y = x_zhou, y_zhou
origin = (x0, y0) # 原点的x, y像素值
loca_x = origin[1] # 坐标轴 x (在y轴上的)的位置
loca_y = origin[0] # 坐标轴 y (在x轴上的)的位置
bili_x, bili_y = 10, 10 # x20尺度y40尺度
# draw_precision = 0.01 #画图精度为Δx
if __name__ == '__main__':
window = tk.Tk()
canvas = tk.Canvas(window,
bg='#CDCDCD',
height=800,
width=1200)
canvas.pack()
screenwidth = window.winfo_screenwidth() # 居中显示
screenheight = window.winfo_screenheight()
size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
window.geometry(size_geo)
window.resizable(False, False)
window_open(width, height)
x_show(x_zhou, y_zhou) # GUI界面
window.bind("<Button-1>", leftclick) # 输出鼠标点击坐标
window.mainloop()

@ -1,47 +0,0 @@
import tkinter as tk
import sympy
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from sympy import symbols, lambdify
def plot_3d_graph(expression):
# 创建 sympy 符号
x, y = symbols('x y')
# 将表达式转换为可计算的函数
expr = lambdify((x, y), expression, modules=['numpy'])
# 创建数据网格
X = np.linspace(-10, 10, 1000)
Y = np.linspace(-10, 10, 1000)
X, Y = np.meshgrid(X, Y)
Z = expr(X, Y)
# 创建一个 Figure 对象
fig = Figure(figsize=(6, 6), dpi=100)
# 在 Figure 上创建一个 3D 子图
ax = fig.add_subplot(111, projection='3d')
# 绘制三维图形
ax.plot_surface(X, Y, Z, cmap='viridis')
# 创建一个 tkinter 窗口
root = tk.Tk()
root.title("3D Graph")
# 在 tkinter 窗口上创建一个 canvas
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack()
# 运行 tkinter 主循环
tk.mainloop()
# 输入要绘制的数学公式
expression = "gamma(x)"
# 使用 sympy 解析数学公式
parsed_expression = sympy.sympify(expression)
# 调用函数绘制三维图形
plot_3d_graph(parsed_expression)

@ -59,9 +59,9 @@ class Graph(Canvas):
for i in range(-math.ceil((self.height - self.origin[1]) / self.bili_y) + 1,
math.ceil((self.origin[1] / self.bili_y))):
j = -(i * self.bili_y)
if (i == 0):
if i == 0:
continue
elif (i % 2 == 0):
elif i % 2 == 0:
self.create_line(self.origin[0], j + self.origin[1], self.origin[0] + 5, j + self.origin[1],
fill='black')
self.create_text(self.origin[0] - 10, j + self.origin[1], text=i)
@ -351,6 +351,10 @@ class FunctionDisplay(Frame):
if __name__ == '__main__':
from pycallgraph2 import PyCallGraph
from pycallgraph2.output import GraphvizOutput
from pycallgraph2 import Config
from pycallgraph2 import GlobbingFilter
root = Window()
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
@ -362,6 +366,17 @@ if __name__ == '__main__':
(screenheight - root_attr['height']) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
output = GraphvizOutput(font_size=30)
output.output_file = "basic.png"
output.group_font_size = 40
config = Config()
config.trace_filter = GlobbingFilter(include=[
'FunctionDisplay.*',
'Graph.*',
'ExpressionCanvas.*',
'FunctionUtil.*'
])
with PyCallGraph(output=output, config=config):
app = FunctionDisplay(root, root_attr)
ttk.Style().configure("TButton", font="-size 18")
ttk.Style().configure("TRadiobutton", font="-size 18")

@ -1 +1 @@
{"xy": "x*y", "f2": "sin(x) * cos(x)", "2sinx": "2*sin(x)", "2cosx": "2*cos(x)", "2xy": "2*x*y", "SinPlusCos(x)": "sin(x) + cos(x)"}
{"xy": "x*y", "f2": "sin(x)* cos(y)"}
Loading…
Cancel
Save