Last active
October 17, 2024 17:20
-
-
Save jul/44d1ee840968faee589fc6bd8675c36b to your computer and use it in GitHub Desktop.
using python with tk directly and matplotlib to plot 3D functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from time import time, sleep | |
from subprocess import Popen, PIPE | |
import os | |
import matplotlib.pyplot as plt | |
import numpy as np | |
from numpy import * | |
import select | |
from matplotlib import cm | |
# let's talk to tk/tcl directly | |
p = Popen(['wish'], stdin=PIPE, stdout=PIPE, stderr=PIPE) | |
os.set_blocking(p.stdout.fileno(), False) | |
os.set_blocking(p.stdin.fileno(), True) | |
os.set_blocking(p.stderr.fileno(), False) | |
def puts(s): | |
for l in s.split("\n"): | |
select.select([], [p.stdin],[]) | |
p.stdin.write((l + "\n").encode()) | |
p.stdin.flush() | |
if back := p.stderr.read(): | |
print("TCL>" + back.decode()) | |
def gets(): | |
ret=p.stdout.read() | |
if ret: | |
exec(ret, globals()) | |
xmin = -5 | |
xmax = 5 | |
xstep = .20 | |
ymin = -5 | |
ymax = 5 | |
ystep = .20 | |
zmin = -1 | |
zmax = 1 | |
puts(f""" | |
set code [ catch {{ | |
source /usr/share/tcltk/ttkthemes/themes/plastik/plastik.tcl | |
ttk::style theme use plastik | |
}} pass ] | |
if {{$code}} {{ | |
puts "print('theme not found, fallback to ugly tcl/tk look')" | |
puts "print('on debian : apt install tcl-ttkthemes to have ttkthemes installed')" | |
}} | |
set text "cos(x) * sin(y) / ( x**2 + y**2 + 1)" | |
proc submit {{}} {{ | |
global text xmax xmin xstep ymax ymin ystep zmax zmin | |
puts "compute('$text');xmax=$xmax;xmin=$xmin;xstep=$xstep;ymin=$ymin;ymax=$ymax;ystep=$ystep;zmin=$zmin;zmax=$zmax" | |
}} | |
pack [ ttk::frame .a ] -anchor s -fill both -expand 1 | |
pack [ ttk::labelframe .t -text plotter ] -padx 5 -pady 5 -fill both -expand 1 -in .a | |
pack [ ttk::frame .f ] -in .t -anchor s -fill both -expand 1 | |
pack [ ttk::label .l -text "Function to plot" ] -in .f -side left | |
pack [ ttk::entry .e -textvariable text -width 32 ] -in .f -side left | |
#bind .e <Enter> submit | |
set xmin {xmin} | |
set xmax {xmax} | |
set xstep {xstep} | |
pack [ ttk::frame .g ] -in .t -anchor s -fill both -expand 1 | |
pack [ ttk::label .lxmin -text "xmin " ] -in .g -side left | |
pack [ ttk::entry .xmin -textvariable xmin -width 3 ] -in .g -side left | |
pack [ ttk::label .lxmax -text " xmax " ] -in .g -side left | |
pack [ ttk::entry .xmax -textvariable xmax -width 3 ] -in .g -side left | |
pack [ ttk::label .lxstep -text " by " ] -in .g -side left | |
pack [ ttk::entry .xstep -textvariable xstep -width 3 ] -in .g -side left | |
set ymin {ymin} | |
set ymax {ymax} | |
set ystep {ystep} | |
pack [ ttk::frame .h ] -in .t -anchor s -fill both -expand 1 | |
pack [ ttk::label .lymin -text "ymin " ] -in .h -side left | |
pack [ ttk::entry .ymin -textvariable ymin -width 3 ] -in .h -side left | |
pack [ ttk::label .lymax -text " xmax " ] -in .h -side left | |
pack [ ttk::entry .ymax -textvariable ymax -width 3 ] -in .h -side left | |
pack [ ttk::label .lystep -text " by " ] -in .h -side left | |
pack [ ttk::entry .ystep -textvariable ystep -width 3 ] -in .h -side left | |
set zmin {zmin} | |
set zmax {zmax} | |
pack [ ttk::frame .i ] -in .t -anchor s -fill both -expand true | |
pack [ ttk::label .lzmin -text "zmin " ] -in .i -side left | |
pack [ ttk::entry .zmin -textvariable zmin -width 3 ] -in .i -side left | |
pack [ ttk::label .lzmax -text " xmax " ] -in .i -side left | |
pack [ ttk::entry .zmax -textvariable zmax -width 3 ] -in .i -side left | |
pack [ ttk::frame .j ] -anchor s -fill both -expand true | |
pack [ ttk::label .lwar -text "Close the matplotlib windows to change the function or parameters" ] -in .j -anchor s | |
set status "" | |
pack [ ttk::label .status -textvariable status ] -in .j -anchor s | |
pack [ ttk::button .b -text Submit -command submit ] -anchor s -in .j | |
""") | |
def compute(text): | |
global plt | |
fig, ax = plt.subplots() | |
ax = fig.add_subplot(projection="3d") | |
xa= np.arange(xmin,xmax,xstep) | |
ya= np.arange(ymin,ymax,ystep) | |
x, y = np.meshgrid(xa,ya) | |
ax.set_zlim(zmin,zmax) | |
try: | |
z= eval(text) | |
s = ax.plot_surface(x,y,z,cmap=cm.coolwarm, antialiased=True) | |
ax.contourf(x, y, z, zdir='z', offset=zmin, cmap='coolwarm') | |
ax.contourf(x, y, z, zdir='x', offset=xmin-xstep, cmap='coolwarm') | |
ax.contourf(x, y, z, zdir='y', offset=ymin-ystep, cmap='coolwarm') | |
f = fig.colorbar(s, shrink=0.5, aspect=10) | |
plt.ioff() | |
plt.show() | |
except Exception as e: | |
puts(f"""tk_messageBox -icon error -message "Python Error : {e}" """) | |
#compute("cos(x)*cos(y)") | |
while True: | |
gets() | |
sleep(1) |
Author
jul
commented
Oct 17, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment