0

I have written a python3.x script to make a plot from matplotlib, and tkinter is used for a dialog window to enter a title, and then to browse for the data files to be used. after a lot of testing everything is working as I want, except that after I close the plot window the program is still running. I have to close the terminal window or reset the kernal in Ipython/jupyter. Is there a simple way to terminate the program when the pyplot is closed?

Note, I am really new to programming, and a lot of this is stitched together from tutorials and other forum questions. I am thinking one possible problem is the way that I am backending (matplotlib says that use() is not the preferred way to do it), and maybe a solution could be found by setting up a loop to ask if I want to make another plot. Another possibility is to put the plot into a tkinter window, but honestly I just taught myself tkinter today as a way to open a browser to select the data files.

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np
import tkinter
from tkinter import Tk
from tkinter import ttk
from tkinter.filedialog import askopenfilename


plot_title = ""  #placeholder variable
wavelength = ""  #placeholder variable

def get_plot_title():
    global plot_title 
    plot_title = title_entry.get()
    title_entry.delete(0, tkinter.END)
    return plot_title

def get_wavelength():
    global wavelength
    wavelength = wavelength_entry.get()
    wavelength_entry.delete(0, tkinter.END)
    return wavelength

root = Tk()
root.geometry('400x400')

rows = 0
while rows < 10:
    root.rowconfigure(rows, weight=1)
    root.columnconfigure(rows,weight=1)
    rows += 1

title_label = ttk.Label(root, text="Enter TeX style name for plot title.\n (e.g., SrTiO3 would be SrTiO_{3})")
title_label.grid(row=1, column=4)

title_entry = ttk.Entry(root)
title_entry.grid(row=2, column=4)
title_entry.insert(0, 'Enter plot title here')

title_button = ttk.Button(root)
title_button.configure(text='Enter Plot Title', command=get_plot_title)
title_button.grid(row=3, column=4)


title_label = ttk.Label(root, text="Enter diffraction wavelength in Angstroms")
title_label.grid(row=5, column=4)

wavelength_entry = ttk.Entry(root)
wavelength_entry.grid(row=6, column=4)
wavelength_entry.insert(0, 'Enter wavelength here')

wavelength_button = ttk.Button(root)
wavelength_button.configure(text='Enter Wavelength', command=get_wavelength)
wavelength_button.grid(row=7, column=4)

root.mainloop()

##############

Tk().withdraw()

obs_file  = askopenfilename(title = "Select the Observed data file.")
calc_file = askopenfilename(title = "Select the Calcualted data file.")
diff_file = askopenfilename(title = "Select the Difference data file.")
hkl_file  = askopenfilename(title = "Select the hkl data file.")

obs_x, obs_y = np.loadtxt(obs_file, unpack=True)
plt.plot(obs_x, obs_y, 'k.', label='Observed', markersize = 3)

plt.yticks([])

calc_x, calc_y = np.loadtxt(calc_file, unpack=True)
plt.plot(calc_x, calc_y, 'r', label='Calculated')

diff_x, diff_y = np.loadtxt(diff_file, unpack=True)
diff_offset = 100
plt.plot(diff_x, diff_y - diff_offset, color='grey', label='Difference')

rslt_h, rslt_k, rslt_l, rslt_m, rslt_d, rslt_Th2, rslt_lp = np.loadtxt(hkl_file, unpack=True)
rslt_Th2_offset = np.full((len(rslt_Th2), 1), (min(diff_y)-150))

plt.plot(rslt_Th2, rslt_Th2_offset, 'k|', label='hkl')


plt.axis([min(obs_x), max(obs_x), None, None])
plot_title = "$" + str(plot_title) + "$"
plt.text(((max(obs_x)-min(obs_x))/2 ), max(obs_y), plot_title, fontsize=12)
x_axis_label = r'$2\theta (\degree), \lambda = $' + wavelength + ' $\AA $'
plt.xlabel(x_axis_label)
plt.ylabel('Intensity (arb. uints)')
plt.legend()
plt.show()
Eric
  • 23
  • 2
  • Instead of `Tk().withdraw()`, try `root.withdraw()`. – Thomas Kühn Dec 14 '18 at 09:59
  • ...and after you are done with your file dialogs, call `root.destroy()`, [see here](https://stackoverflow.com/a/1407700/2454357). – Thomas Kühn Dec 14 '18 at 10:02
  • I have tried replacing the `Tk().withdraw()` as suggested, but when I do I get an error: "TclError: can't invoke "wm" command: application has been destroyed"; regardless, I dont think this is the issue because I can simply remove the withdraw line to be at the same end spot. If I add the `root.destroy()` after the `askopenfilename` lines I get the following error: "TclError: can't invoke "destroy" command: application has been destroyed" – Eric Dec 14 '18 at 20:57
  • Ok, it was just a guess. I'm not really an expert on tkinter and the haven't used it together with matplotlib the way you do. What I have done so far is embedding a matplotlib figure in a tkinter window, like it is for instance done in [this question](https://stackoverflow.com/q/4073660/2454357) and that has always worked. Maybe, if nothing better comes up, you could try adapting your program this way ... – Thomas Kühn Dec 14 '18 at 21:07

1 Answers1

-1

I do this with linux command, it shows all open python processes then i kill it usig its PID

ps aux | grep python
kill 1234
Edmhs
  • 3,645
  • 27
  • 39