Я работаю над приложением Python 3.4 для отображения графиков плотности мощности для сигналов ЭЭГ. Я хочу наложить цветовые пятна на графики, чтобы указать стандартные полосы частот для дельта, тета, альфа, бета и гамма.Неожиданное поведение matplotlib.patches при изменении размера окна
Программа скелета ниже показывает, как график появляется во всплывающем окне при нажатии кнопки дисплея. Все отлично при изменении размера первого всплывающего окна. Проблема возникает при изменении размера второго всплывающего окна (при повторном нажатии кнопки дисплея). Затем цветные пятна появляются в неправильных местах и не соответствуют указанным полосам частот.
import tkinter as tk
from tkinter import BOTH, TOP, Y
from tkinter import ttk
from tkinter import Frame
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# The following is used for psd semi-log graphs only
XMIN = 0 # minimum frequency
XMAX = 55 # maximum frequency
YMIN = 0.1 # minimum PSD value
YMAX = 100 # maximum PSD value
lblY = YMAX - 30
band_patches = [
patches.Rectangle((XMIN, YMIN), 4, YMAX, facecolor="blue", alpha=0.2),
patches.Rectangle((4, YMIN), 4, YMAX, facecolor="cyan", alpha=0.2),
patches.Rectangle((8, YMIN), 4, YMAX, facecolor="green", alpha=0.2),
patches.Rectangle((12, YMIN), 18, YMAX, facecolor="orange", alpha=0.2),
patches.Rectangle((30, YMIN), XMAX-30, YMAX, facecolor="magenta", alpha=0.2),
]
class PV(ttk.Frame):
def __init__(self, name='demo'):
ttk.Frame.__init__(self, name=name)
self.pack(expand=Y, fill=BOTH)
self.master.title('Demo')
self._create_viewer_panel()
def _create_viewer_panel(self):
viewerPanel = Frame(self, name='pv')
viewerPanel.pack(side=TOP, fill=BOTH, expand=Y)
# create the notebook
nb = ttk.Notebook(viewerPanel, name='notebook')
nb.enable_traversal()
nb.pack(fill=BOTH, expand=Y, padx=2, pady=3)
self._create_UI_tab(nb) #NEW
def _create_UI_tab(self, nb):
# frame to hold contentx
self.frame = ttk.Frame(nb, height='10i', width='8i', name='main')
btn0 = ttk.Button(self.frame, text='Display', width='25', command=self.draw_psd)
btn0.grid(row=0, column=1)
# add to notebook (underline = index for short-cut character)
nb.add(self.frame, text='Main', underline=0, padding=2)
def draw_psd(self):
popup = tk.Tk()
popup.geometry('720x480') # Set dimensions of popup window to 800x500 pixels
popup.wm_title("Power Spectral Density")
p = plt.figure()
self.ax = plt.subplot(111)
box = self.ax.get_position()
self.ax.set_position([box.x0, box.y0, box.width, box.height*0.95])
self.ax.set_yscale('log')
self.ax.set_xscale('linear')
plt.xlabel('Frequency (Hz)')
plt.xlim(XMIN, XMAX)
plt.ylim(YMIN, YMAX)
for ptch in band_patches:
self.ax.add_patch(ptch)
self.ax.annotate('delta', xy=(2,lblY), fontsize=10, color=None, horizontalalignment='center')
self.ax.annotate('theta', xy=(6,lblY), fontsize=10, color=None, horizontalalignment='center')
self.ax.annotate('alpha', xy=(10,lblY), fontsize=10, color=None, horizontalalignment='center')
self.ax.annotate('beta', xy=(21,lblY), fontsize=10, color=None, horizontalalignment='center')
self.ax.annotate('gamma', xy=(42,lblY), fontsize=10, color=None, horizontalalignment='center')
plt.show()
canvas = FigureCanvasTkAgg(p, master=popup)
canvas.show()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
toolbar = NavigationToolbar2TkAgg(canvas, popup)
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP, expand=1)
popup.mainloop()
return None
if __name__ == '__main__':
PV().mainloop()
Я подозреваю, что это проблема с инициализацией координат, но я не понимаю, как это исправить. Какие-либо предложения?
Oblivion, спасибо за проницательный и замечательный ответ. Я применил ваше предложение использовать Toplevel для вторичных окон и решает проблему изменения размера этих окон. Избавиться от «интерфейса pyplot» будет значительно сложнее - в моем коде есть десятки вхождений plt и их замена - дело не простое. На данный момент всплывающие окна для временных рядов-графиков, спектрограмм, радиолокационных карт, похоже, работают нормально. Я полагаю, что могут быть скрытые проблемы, но я не понимаю, почему это проблема. –