Как разместить текстовое поле в сюжете matplotlib, не открывая два окна? - PullRequest
0 голосов
/ 07 февраля 2019

Я пишу небольшую программу, используя 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...