Я пишу небольшую программу, используя tkinter и matplotlib, которая строит кривую нормального распределения и доверительный интервал.Я хочу, чтобы на графике было небольшое текстовое поле в верхнем левом углу с использованием plt.text()
, в котором хранится некоторая информация о входных данных пользователя и некоторая другая релевантная информация, рассчитанная по базовой модели (например, надежность, нормальное значение и т. Д.).
Я явно хочу избежать использования fig, ax = plt.subplots()
, так как это откроет два окна (где одно пустое, а другое содержит график).
Однако я понял, что мне нужно создать подзаговор, чтобы использовать transform=ax.transAxes
и убедиться, что текстовое поле появляется в моем окне графика (см. текстовая подпись не отображается matplotlib ).Без этого ключевого аргумента я вынужден использовать явные координаты данных, которые я не могу сделать, так как координаты оси могут меняться в зависимости от ввода пользователя.
Как разместить текстовое поле в верхнем левом углу, не открывая два окна?
Вот мой код:
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
import numpy as np
import math
from scipy.stats import norm
from scipy.stats import zscore
class Application:
def __init__(self, master):
self.master = master
self.callPlotWindow()
def callPlotWindow(self):
plotdata = dict()
plotdata['reliability'] = 0.94
plotdata['sd'] = 10
plotdata['mean'] = 50
plotdata['normvalue'] = 66
plotdata['confidence_level'] = '80%'
plotdata['question'] = 'einseitig'
plotdata['hypothesis'] = 'Äquivalenzhypothese'
plotdata['plot_ci'] = 4.12298113505264
plotdata['plot_ci_lower'] = 63.93850943247368
plotdata['plot_ci_upper'] = 68.06149056752632
# turn on interactive mode
plt.ion()
# if there is already a plot window clear old plot
if plt:
plt.clf()
# create x values for normal distribution
x_normdist = np.concatenate((
np.linspace(plotdata["mean"] - 3 * plotdata["sd"], plotdata["mean"] - 2 * plotdata["sd"],endpoint=False),
np.linspace(plotdata["mean"] - 2 * plotdata["sd"], plotdata["mean"] - 1 * plotdata["sd"],endpoint=False),
np.linspace(plotdata["mean"] - 1 * plotdata["sd"], plotdata["mean"] + 1 * plotdata["sd"],endpoint=False),
np.linspace(plotdata["mean"] + 1 * plotdata["sd"], plotdata["mean"] + 2 * plotdata["sd"],endpoint=False),
np.linspace(plotdata["mean"] + 2 * plotdata["sd"], plotdata["mean"] + 3 * plotdata["sd"])
))
# plot normal distribution curve
y_normdist = norm.pdf(x_normdist,plotdata["mean"],plotdata["sd"])
plt.plot(x_normdist,y_normdist)
# create logical lists which are used for 'where'-argument in fill-between method
average = (x_normdist >= (plotdata["mean"] - 1 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] + 1 * plotdata["sd"]))
above_and_below_average = (x_normdist >= (plotdata["mean"] - 2 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] - 1 * plotdata["sd"])) | (x_normdist >= (plotdata["mean"] + 1 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] + 2 * plotdata["sd"]))
far_above_and_below_average = (x_normdist >= (plotdata["mean"] - 3 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] - 2 * plotdata["sd"])) | (x_normdist >= (plotdata["mean"] + 2 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] + 3 * plotdata["sd"]))
regions = [average,
above_and_below_average,
far_above_and_below_average
]
alpha_values = [0.75,0.5,0.25]
region_labels = [
"durchschnittlich",
"unter-/überdurchschnittlich",
"weit unter-/überdurchschnittlich"
]
# shade regions under curve, use different alpha channel values and labels
for idx,region in enumerate(regions):
plt.fill_between(x_normdist, y_normdist,color="C0",alpha=alpha_values[idx],label=region_labels[idx],where=regions[idx])
# plot confidence interval
plt.errorbar(x=plotdata["normvalue"],y=0,xerr=plotdata["plot_ci"],fmt=".k",capsize=10)
# set x and y axis title
plt.xlabel(xlabel="Normwert")
plt.ylabel(ylabel=r'$\phi_{\mu\sigma}(\mathcal{X})$')
textstr = '\n'.join((
r'$Normwert: %.2f$' % (plotdata["normvalue"], ),
r'$Reliabilität: %.2f$' % (plotdata["reliability"], ),
r'$Mittelwert des Normwertes: %.2f$' % (plotdata["mean"], ),
r'$Standardabweichung des Normwertes: %.2f$' % (plotdata["sd"],),
r'$Untere KI-Grenze: %.2f$' % (round(plotdata["plot_ci_lower"],2),),
r'$Obere KI-Grenze: %.2f$' % (round(plotdata["plot_ci_upper"],2),),
))
# these are matplotlib.patch.Patch properties
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
# create legend
plt.legend(loc='upper right', prop={'size': 8})
# place a text box in upper left in axes coords
plt.text(0.05, 0.95,textstr,fontsize=14,verticalalignment='top',bbox=props)
if __name__ == "__main__":
root = tk.Tk()
my_gui = Application(root)
root.mainloop()