#python #matplotlib
#python #matplotlib
Вопрос:
Я пытаюсь создать график с использованием matplotlib, в котором даты будут извлечены из файлов в качестве основного тика, а часы — в качестве второстепенных тиков. В коде, который у меня есть до сих пор, есть это, хотя весь текст сгруппирован — меня это сейчас не беспокоит. Моя проблема в том, что если бы я увеличивал масштаб или панорамировал, тики и их соответствующие значения не обновлялись. Например, если бы я увеличил масштаб до одного дня, все дни по-прежнему отображались на оси x. Я использую Spyder в качестве своей IDE и Python 2.7. Кроме того, я должен просто выбросить это: я новичок как в Python, так и в программировании в целом.
hticks = []
tickcnt = 0
for i in range(len(MBTempvalue)):
mcnt = mcnt 1
cnt = cnt 1
if mcnt == 60:
mcnt = 0
harray.append(str(hcnt))
hcnt = hcnt 1
tickcnt = tickcnt 1
hticks.append(tickcnt)
if hcnt == 24:
hcnt = 0
if cnt == 1375:
cnt = 0
days = days 1
hours = days * 24
fig = plt.figure(figsize = (8,6))
ax = fig.add_subplot(211)
xmax = float(len(PS0AmbientTempvalue))
dx = hours/xmax
y = PS0AmbientTempvalue
y2 = PS1AmbientTempvalue
x = np.arange(0,hours, dx)
plt.xticks(darray,date)
ax.xaxis.set_major_locator(LinearLocator(len(darray)))
minorLocator = AutoMinorLocator(23)
ax.xaxis.set_minor_locator(minorLocator)
minorformatter = FixedFormatter(harray)
ax.xaxis.set_minor_formatter(minorformatter)
l1, l2, l3, l4 = ax.plot(x,y, 'b', x, PS0AmbientTempavgline, 'r', x, y2, 'y', x, PS1AmbientTempavgline, 'g')
#plt.xlabel('Hours')
plt.ylabel('Temp - C')
plt.title(' PS0/T_AMB and PS1/T_AMB')
plt.axis([0, hours, (minscale1-5), (maxscale1 5)])
plt.grid(True)
fig.legend((l1,l2,l3,l4), ('PS0 Act', 'PS0 Avg', 'PS1 Act', 'PS1 Avg'), 'upper right')
plt.annotate(('PS0 Max = ' PS0AmbientTempstrmax), (0,0), (0, -70), xycoords = 'axes fraction', textcoords = 'offset points', va ='bottom')
plt.annotate(('PS0 Min = ' PS0AmbientTempstrmin), (0,0), (0, -90), xycoords = 'axes fraction', textcoords = 'offset points', va = 'bottom')
plt.annotate(('PS0 Avg = ' PS0AmbientTempstravg), (0,0), (0, -110), xycoords = 'axes fraction', textcoords = 'offset points', va ='bottom')
plt.annotate(('PS0 Stand Dev = ' PS0AmbientTempstrstandev), (0,0), (0, -130), xycoords = 'axes fraction', textcoords = 'offset points', va ='bottom')
plt.annotate(('PS 1Max = ' PS1AmbientTempstrmax), (0,0), (8*hours, -70), xycoords = 'axes fraction', textcoords = 'offset points', va = 'bottom')
plt.annotate(('PS1 Min = ' PS1AmbientTempstrmin), (0,0), (8*hours, -90), xycoords = 'axes fraction', textcoords = 'offset points', va = 'bottom')
plt.annotate(('PS1 Avg = ' PS1AmbientTempstravg), (0,0), (8*hours, -110), xycoords = 'axes fraction', textcoords = 'offset points', va = 'bottom')
plt.annotate(('PS1 Stand Dev = ' PS1AmbientTempstrstandev), (0,0), (8*hours, -130), xycoords = 'axes fraction', textcoords = 'offset points', va = 'bottom')
Любая помощь будет принята с благодарностью.
Спасибо!
Крис
Ответ №1:
Причина, по которой они не обновляются, заключается в том, что вы используете a FixedFormatter
, которые, как следует из названия, исправлены. Основная задача для этого — наложение текстовых меток на метки (например, создание столбчатых графиков, где ось x является качественной, а не количественной). mpl делает именно то, что вы ему сказали.
matplotlib может напрямую отображать datetime
объекты, что, вероятно, и является тем, что вы хотите сделать здесь.
См. api и кулинарную книгу.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
numdays = 5
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(hours=x) for x in range(0, numdays*24)]
data = np.random.rand(len(date_list))
fig, ax = plt.subplots(1, 1)
ax.plot(date_list, data)
ax.xaxis.set_major_locator(mdates.DayLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax.xaxis.set_minor_locator(mdates.HourLocator())
fig.autofmt_xdate()
plt.draw()
plt.show()
Комментарии:
1. Человек! Это было ОЧЕНЬ полезно! Я совсем не знаком с методом datetime. Есть ли способ изменить его так, чтобы вместо бесконечного обратного отсчета он отсчитывался до определенной даты? Например, у меня будет дата начала и дата остановки.
2. Я действительно не понимаю, что вы пытаетесь сделать.
3. Я новичок, поэтому, вероятно, использую не самые лучшие слова для описания моей ситуации. Извините. У пользователя будет диапазон файлов, в которых даты ввода данных являются частью имени файла. На основе выбора пользователем этого диапазона определяется количество дней, которые я хочу отобразить, и многим из этих файлов 4 года. Итак, я предполагаю, что я говорю, что даты будут определяться пользователем — они будут переменными. На самом деле, что у меня есть на данный момент, так это то, что диапазон дат находится в списке, в котором я собирался, чтобы первый элемент был начальной датой, а последний элемент — датой остановки.
Ответ №2:
Большое спасибо tcaswell за помощь! Я бы не смог решить свою проблему без вашей помощи! Вот код, который я использую:
def kuVpolFunc2(kuvdate, kuvit, kuviti, kuvfp, kuvfpi, faultflag):
import matplotlib.pyplot as plt
import numpy as np
import re
import matplotlib.dates as mdates
import datetime
from datetime import timedelta
kutempvalue = kuvit
kutempinter = kuviti
kufpvalue = kuvfp
kufpinter = kuvfpi
faultflagit = faultflag
date = kuvdate
datelist = []
#I first had to decontruct the filename pulled from the directory to put it in a format that Python could then create a datetime object.
for n in date:
month = n[:3]
datenum = re.sub("[^0-9]","", n)
day = str(datenum[:-4])
year = str(datenum[2:])
print ("Year: " year)
print ("Month: " month)
print ("Day: " day)
alltogether = str(month ' ' day ' ' year)
dateobject = datetime.datetime.strptime(alltogether, '%b %d %Y')
datelist.append(dateobject)
start = min(datelist)
dlist = [start timedelta(minutes = x) for x in range(0, len(datelist) *1440)]
#The 'add' variable is used to make sure that the dlist's dimension is the same as the data. It isn't posted here for brevity's sake, but I can post it if someone wants it.
add = max(dlist)
fig, ax = plt.subplots(1,1)
l1, l2, = ax.plot(dlist, y, 'b', dlist, kutempavgline, 'r')
ax.xaxis.set_major_locator(mdates.DayLocator())
plt.title('Ku_Vpol Internal Temp')
plt.ylabel('Temp - C')
fig.legend((l1,l2), ('Internal Temp Actual Temp', 'Internal Temp Average Temp'), 'upper right')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax.xaxis.set_minor_locator(mdates.HourLocator())
plt.grid(True)
fig.autofmt_xdate()
plt.draw()
plt.show()