Вопрос-Ответ

Difference in plotting with different matplotlib versions

Разница в построении графиков с разными версиями matplotlib

Мой коллега передал мне скрипт, который используется для сбора данных из базы данных и их построения. Когда я сам использовал скрипт, графики выглядели по-разному, и это связано с версией Matplotlib.

Скрипт, который выполняет построение графиков данных, довольно короткий:

import matplotlib.pyplot as plt
import csv
import os
from dateutil import parser

def plot(outputDir,plotsDir,FS):
allfiles = os.listdir(outputDir)
flist = []
for f in allfiles:
if 'csv' in f.lower(): flist.append(f)
for f in flist:
with open(outputDir + '/' + f, 'rt') as ff:
data = list(csv.reader(ff,delimiter=FS))
values = [i[2] for i in data[1::]]
values = ['NaN' if v is '' else v for v in values]
time = [parser.parse(i[1]) for i in data[1::]]
plt.xlabel('Time_[UTC]')
plt.plot(time, values)
plt.xticks(rotation=40)
if os.path.isdir(plotsDir) != 1:
os.mkdir(plotsDir, 777)
plt.savefig('{}/{}_Data.png'.format(plotsDir, f[:-4]), bbox_inches='tight', dpi=160)
plt.clf()


outputdir = 'C:/Users/matthijsk/Documents/Test'
plotsdir = outputdir + '/plots'
fs = ','
plot(outputdir, plotsdir, fs)

Когда я запускаю его с использованием Matplotlib версии 2.1.0, мое изображение выглядит следующим образом:
Matplotlib версии 2.1.0
Когда я запускаю его с использованием Matplotlib версии 2.0.2, он выглядит так, как и должен:
Matplotlib версии 2.0.2

Файл, который читает скрипт, выглядит следующим образом:

stationNo,dtg(UTC),TT_[°C],source_TT,quality_TT
10381,2017-01-01 00:00:00,3.0,ob,na
10381,2017-01-01 01:00:00,3.0,ob,na
10381,2017-01-01 02:00:00,2.4,ob,na
10381,2017-01-01 03:00:00,2.5,ob,na
10381,2017-01-01 04:00:00,2.5,ob,na
10381,2017-01-01 05:00:00,2.3,ob,na
10381,2017-01-01 06:00:00,1.9,ob,na
10381,2017-01-01 07:00:00,1.0,ob,na
10381,2017-01-01 08:00:00,0.1,ob,na
10381,2017-01-01 09:00:00,0.9,ob,na

Кто-нибудь может объяснить мне, что было изменено в Matplotlib, что вызвало это? И, очевидно, я делаю что-то не так с построением графика, что является причиной этого. Кто-нибудь заметил ошибку?
Я уже пробовал использовать

values = [float(value) if value.isnumeric() else None for value in values]

Но это не решило проблему.
Примечание: Я бы предпочел не использовать какие-либо нестандартные пакеты (например, Pandas), поскольку получить разрешение на установку таких пакетов довольно сложно.

Переведено автоматически
Ответ 1

Данные считываются в виде строк. В matplotlib 2.0 они были автоматически преобразованы в числа с плавающей запятой, чтобы их можно было построить.

В matplotlib 2.1 были введены категориальные графики. Теперь это позволяет выполнять что-то вроде

plt.plot(["apple", "banana", "cherry"], [2,1,3])

Хотя это, конечно, отлично подходит для определенных приложений, это нарушает предыдущий вариант построения строк, которые можно преобразовать в значения с плавающей точкой. Я думаю, что если это нормально, это просто возлагает на пользователя ответственность за выполнение преобразования самостоятельно.

В этом случае вы хотели бы выполнить это преобразование следующим образом

values = [None if v is '' else float(v) for v in values]

На случай, если у вас уже есть массив numpy: np.array(values).astype(float)

В общем, можно использовать numpy.loadtxt для чтения файлов в массивы с плавающей точкой. Если файл содержит даты, возможно использование преобразователя, как при чтении файла, разделенного запятыми, с объектом date и с плавающей точкой с помощью Python.

Другим вариантом чтения в текстовых файлах было бы pandas.read_csv.

python matplotlib