Построение постоянного текста на графике в python - PullRequest
0 голосов
/ 06 марта 2020

Я уверен, что, возможно, задаю тупой вопрос, но не смог найти другой такой же, как у меня.

Мой друг помог мне написать код для анализа, дать данные и построить их с линией тренда, Я хотел бы добавить строку текста в правом верхнем углу графика с другими вещами, напечатанными на графике, в которых указано, что это за файл (который записан как константа в другом месте кода).

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from numpy import exp, loadtxt, pi, sqrt, random, linspace
from lmfit import Model
import glob, os

## Define gaussian
def gaussian(x, amp, cen, wid):
    """1-d gaussian: gaussian(x, amp, cen, wid)"""
    return (amp / (sqrt(2*pi) * wid)) * exp(-(x-cen)**2 / (2*wid**2))

## Define exponential decay
def expdecay(x, t, A): 
     return A*exp(-x/t)

## Define constants
fileToRun = 'Run15'
folderId = '\\'
baseFolder = 'C:'+folderId+'Users'+folderId+'ControlRoom6'+folderId+'Documents'+folderId+'PhD'+folderId+'Ubuntu-Analysis-DCF'+folderId+'DCF-an-b+decay'+folderId+'dcp-ap-27Al'+folderId+''
prefix = 'DECAY_COINC'
stderrThreshold = 10
minimumAmplitude = 0.1
approxcen = 780
MaestroT = 18

## Define paramaters
amps = []; ampserr = []; ts = []
folderToAnalyze = baseFolder + fileToRun + '\\'

## Gets number of files
files = []
os.chdir(folderToAnalyze)
for file in glob.glob(prefix + "*.Spe"):
    files.append(file)
numfiles = len(files)
if numfiles<=1:
    print('numfiles is {0}, minimum of 2 is required'.format(numfiles))
    raise SystemExit(0)

## Generate the time array

for n in range(0, numfiles):

    ## Print progress
    print('\rFile {0} / {1}'.format(n+1, numfiles), end='')

    ## Load text file
    x = np.linspace(0, 8191, 8192) 
    fullprefix = folderToAnalyze + prefix + str(n).zfill(3)
    y = loadtxt(fullprefix + ".Spe", skiprows= 12, max_rows = 8192) 

    ## Make figure
    fig, ax = plt.subplots(figsize=(15,8))
    fig.suptitle('Coincidence Detections', fontsize=20)
    plt.xlabel('Bins', fontsize=14)
    plt.ylabel('Counts', fontsize=14)

    ## Plot data
    ax.plot(x, y, 'bo')
    ax.set_xlim(600,1000)

    ## Fit data to Gaussian
    gmodel = Model(gaussian)
    result = gmodel.fit(y, x=x, amp=8, cen=approxcen, wid=1)

    ## Plot results and save figure
    ax.plot(x, result.best_fit, 'r-', label='best fit')
    ax.legend(loc='best')
    texttoplot = result.fit_report()
    ax.text(0.02, 0.5, texttoplot, transform=ax.transAxes)
    plt.close()
    fig.savefig(fullprefix + ".png", pad_inches='0.5')

    ## Print progress
    if n==numfiles-1:
        print('\rDone')

    ## Append to list if error in amplitude and amplitude itself is within reasonable bounds
    if result.params['amp'].stderr < stderrThreshold and result.params['amp'] > minimumAmplitude:
        amps.append(result.params['amp'].value) 
        ampserr.append(result.params['amp'].stderr) 
        ts.append(MaestroT*n)

## Plot decay curve
fig, ax = plt.subplots()
ax.errorbar(ts, amps, yerr= 2*np.array(ampserr), fmt="ko-", capsize = 5, capthick= 2, elinewidth=3, markersize=5)
plt.xlabel('Time', fontsize=14)
plt.ylabel('Peak amplitude', fontsize=14)

## Fit decay curve
emodel = Model(expdecay)
decayresult = emodel.fit(amps, x=ts, weights=1/np.array(ampserr), t=150, A=140)
ax.plot(ts, decayresult.best_fit, 'r-', label='best fit')

## Add text to plot
plottext = '{filetoRun}\n'
plottext = 'N: {0} / {1}\n'.format(len(ts), numfiles)
plottext += 't: {0:.2f} ± {1:.2f}\n'.format(decayresult.params['t'].value, decayresult.params['t'].stderr)
plottext += 'A: {0:.2f} ± {1:.2f}\n'.format(decayresult.params['A'].value, decayresult.params['A'].stderr)
plottext += 'Reduced $χ^2$: {0:.2f}\n'.format(decayresult.redchi)
ax.text(0.5, 0.55, plottext, transform=ax.transAxes, fontsize=14)
plt.show()

## Save figure
fig.savefig(folderToAnalyze + "A_" + prefix + "_decayplot.pdf", pad_inches='0.5')

Мне бы хотелось (в данном случае Run15 показывать чуть выше, где на этом графике написано «N = 28/50»). Я пробовал разные комбинации скобок и plt.text, но, честно говоря, я действительно не знаю, что делаю, и это все для меня в новинку. Она не отображает ошибку, подобную этой, просто выводит график без нужного текста

Output Graph

1 Ответ

1 голос
/ 06 марта 2020

Я думаю, что вы допустили ошибку, используя = вместо +=, и это то, что не может вывести вашу первую строку с fileToRun.

Кроме этого, ваша интуиция при наведении скобок '{filetoRun}\n' вокруг переменной в строке имеет смысл: это цель Python f-строк! Вам просто нужно использовать спецификатор f перед строкой.

Заменить это:

plottext = '{fileToRun}\n'
plottext = 'N: {0} / {1}\n'.format(len(ts), numfiles)

На это:

plottext = f'{fileToRun}\n'
plottext += 'N: {0} / {1}\n'.format(len(ts), numfiles)

Кстати, хороший сюжет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...