Skip to content

Instantly share code, notes, and snippets.

@jul
Last active October 17, 2024 17:20
Show Gist options
  • Save jul/44d1ee840968faee589fc6bd8675c36b to your computer and use it in GitHub Desktop.
Save jul/44d1ee840968faee589fc6bd8675c36b to your computer and use it in GitHub Desktop.
using python with tk directly and matplotlib to plot 3D functions
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)
@jul
Copy link
Author

jul commented Oct 17, 2024

interface plot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment