Gnuplot, используйте переменную оси X, связанную со временем, и покажите метку дня (когда она меняется в идеале)

У меня есть данные cvs из sqlite3, небольшой отредактированный образец:

conTime деньXS_date Ref-AHx Ref-Cx10 Кровать1-AH Кровать2-АХ Кровать1-Cx10 Кровать2-Cx10 6466 14.05.2024 510 149 583 604 210 222 6467 14.05.2024 510 147 587 601 210 221 6468 14.05.2024 515 143 590 599 210 220 6469 14.05.2024 515 144 582 597 209 220 6470 14.05.2024 517 144 589 596 209 219 6471 14.05.2024 526 144 586 594 208 219 6472 14.05.2024 538 139 583 590 207 218 6473 14.05.2024 542 135 581 587 206 217 6474 14.05.2024 542 134 597 584 205 216 6475 14.05.2024 538 133 597 580 205 215 ......... 6690 20.05.2024 466 206 638 602 232 235 6691 20.05.2024 486 197 651 600 236 240 6692 20.05.2024 510 189 646 640 236 241 6693 20.05.2024 506 181 638 657 235 241 6694 20.05.2024 527 171 613 630 234 238 6695 20.05.2024 528 159 605 662 232 238 6696 20.05.2024 507 145 593 658 230 235 6697 20.05.2024 493 136 587 647 228 232 6698 20.05.2024 485 131 585 587 227 227 6699 20.05.2024 500 133 585 628 226 229

Если я построю столбцы 3+ против 1, все будет хорошо. Я просто хотел бы узнать, где находятся дни (в идеале начало каждого дня) по оси X, но я не хочу, чтобы каждая точка данных имела одну и ту же метку даты.

conTime настраивается в sql, чтобы дать мне плавно увеличивающееся число с соответствующей степенью детализации для моих нужд, поэтому мне действительно нужно, чтобы это было основой оси X.

В псевдокоде я хотел бы (график) метка columns_text(2) точки данных 20; или (график) label columns_text(2) at col(1),-15 'когда он меняется';

Я провел много часов, играя с идеями с www. Текущие их остатки приведены ниже, я в основном вырезаю и вставляю их в интерактивном режиме в сеансы Gnuplot... Если бы у меня работали xticlabels или что-то подобное, их было бы слишком много. Генерация в sql нулевой или измененной даты может сработать, но это также обучение этому и побочный путь от того, чего мне нужно достичь...

set xdata time
set timefmt "%Y/%m/%d"
set format x "%Y-%m-%d"
set xtics rotate by 90 offset 0,-4 

#plot first line heavier weight as clearer ref etc.
#plot  "sqlout.csv" using 1:2 with text dp 10, \
plot "sqlout.csv" using 1:3 with lp lt 1 lw 3 title columnhead(3), \
 "sqlout.csv" using 1:4 with lp lt 2 lw 3 title columnhead(4), \
for [col=5:*] "sqlout.csv" using 1:col with lp ls col title columnhead(col)
#pause -1 "Return to end..."

#pause 2
plot "sqlout.csv" using 2:3 with lp lt 1 lw 3 title columnhead(3), \
 "sqlout.csv" using 2:4 with lp lt 2 lw 3 title columnhead(4), \
for [col=5:*] "sqlout.csv" using 2:col with lp ls col title columnhead(col)

Кстати заставить таблицу работать удалось PITA, добавив | в SQL. БОЛЬШАЯ ПОДСКАЗКА: | ---| --- | клетки кажутся необходимыми???

С момента публикации мне удалось в sql использовать LAG(dayXS_date) только для того, чтобы показывать, где меняются даты, и оставить пустым в противном случае, поэтому построение графика всей оси теперь решило бы и мою проблему. Я даже не знаю, как это сделать!

conTime деньXS_date Ref-AHx Ref-Cx10 Кровать1-AH Кровать2-АХ Кровать1-Cx10 Кровать2-Cx10 6466 14.05.2024 510 149 583 604 210 222 6467 -, 510 147 587 601 210 221 6468 -, 515 143 590 599 210 220

Кажется, я не могу составить здесь таблицу с пустыми ячейками! Превью Отлично!

Зачем создавать сложную таблицу, если ваши данные представляют собой простой текстовый файл, например CSV? Просто скопируйте и вставьте свой CSV-файл сюда, на StackOverflow, между парой тройных обратных кавычек. Насколько я понимаю, вы хотите построить график ежедневных данных с небольшим сдвигом во времени, верно? Сколько точек данных обычно находится в течение одного дня? Это фиксированное число или переменная в определенном диапазоне?

theozh 21.05.2024 19:44

Это было то, что я попробовал в первую очередь, но, похоже, строки объединялись независимо от того, какой стиль цитаты и т. д. я пробовал. может быть, это потому, что он ожидает окончания строк в стиле Windows? Я использую MacOS, поэтому по умолчанию стиль *nix. Но спасибо, я так и думал...

Cwinte 22.05.2024 16:20

Если вы посмотрите на мой SQL ниже, мне действительно нужно собрать строки в столбцы. Для меня это пустая трата времени, особенно когда есть 10*2 категории! Есть ли способ, которым Gnuplot может обрабатывать чтение категории из столбца locationID и при этом выдавать тот же результат? Итак, мои строки данных будут иметь столбцы: ..... conTime, дата, местоположение, AH, Cx10.

Cwinte 22.05.2024 17:26

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

theozh 23.05.2024 15:46
Работа с датами и временем в языке Java
Работа с датами и временем в языке Java
Работа с датами и временем в языке Java была сильно переработана начиная с версии Java 8 и далее с появлением библиотеки java.time.
1
4
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

На данный момент я понимаю ваш вопрос следующим образом: у вас есть некоторые данные о времени, но у данных есть только отметка дня (нет времени в часах/минутах). Поскольку существует несколько точек данных за один и тот же день, они будут отображаться в одной и той же позиции на оси времени. Поскольку вы хотите распределить данные, вы ввели столбец conTime, чтобы немного распределить точки данных. Теперь вопрос в том, как распределить данные в течение дня, верно?

Некоторые комментарии:

  • с помощью опции smooth freq подсчитывается количество точек данных за каждый день. Блок данных $Counts будет содержать время (в секундах, прошедших с 1 января 1970 года) и количество точек данных.
  • getCounts() — это функция «поиска», позволяющая получить количество данных в зависимости от дня.
  • функция spread() инициализирует счетчик c=0 и увеличивает его на 1 каждый раз, когда предыдущее время t0 идентично текущему времени t1. Каждый раз, когда наступает новый день, счетчик сбрасывается на c=0, а c0 получает количество точек данных за этот день. Функция фактически вернет дробь 86400.*c/c0, т.е. данные распределены по дням (86400 секунд = 1 день).

Возможно, это еще можно упростить.

Данные: SO78513320.csv

Просто для иллюстрации я ввел некоторые дополнительные данные, разделенные закомментированными строками для наглядности.

conTime,dayXS_date,Ref-AHx,Ref-Cx10,Bed1-AH,Bed2-AH,Bed1-Cx10,Bed2-Cx10
6466,2024/05/14,510,149,583,604,210,222
6467,2024/05/14,510,147,587,601,210,221
6468,2024/05/14,515,143,590,599,210,220
6469,2024/05/14,515,144,582,597,209,220
6470,2024/05/14,517,144,589,596,209,219
6471,2024/05/14,526,144,586,594,208,219
6472,2024/05/14,538,139,583,590,207,218
6473,2024/05/14,542,135,581,587,206,217
6474,2024/05/14,542,134,597,584,205,216
6475,2024/05/14,538,133,597,580,205,215
#
6480,2024/05/17,538,133,597,580,205,215
6480,2024/05/17,528,143,587,570,215,225
6480,2024/05/17,518,153,577,560,225,235
6480,2024/05/17,538,133,597,580,205,215
#
6690,2024/05/20,466,206,638,602,232,235
6691,2024/05/20,486,197,651,600,236,240
6692,2024/05/20,510,189,646,640,236,241
6693,2024/05/20,506,181,638,657,235,241
6694,2024/05/20,527,171,613,630,234,238
6695,2024/05/20,528,159,605,662,232,238
6696,2024/05/20,507,145,593,658,230,235
6697,2024/05/20,493,136,587,647,228,232
6698,2024/05/20,485,131,585,587,227,227
6699,2024/05/20,500,133,585,628,226,229

Скрипт:

### spread data of one day over 24 hours
reset session

FILE = "SO78513320.csv"

set datafile separator comma
myFmt = "%Y/%m/%d"

set table $Counts
    set format x "%.0f"
    plot FILE u (timecolumn(2,myFmt)):(1) smooth freq
unset table

getCounts(t) = sum [i=5:|$Counts|-2] ($Counts[i]==t ? int(word($Counts[i],2)) : 0)
spread(col)  = (t=timecolumn(col,myFmt), $0==0 ? (c=0, c0=getCounts(t),t1=t) : NaN, \
               t0=t1, t1=t, t0==t1 ? c=c+1 : (c=0, c0=getCounts(t)), t+86400.*c/c0)

set format x "%Y\n%m/%d" timedate
set offsets graph 0.05, graph 0.05, graph 0.05, graph 0.05
set key out
set grid x,y

plot FILE u (spread(2)):3 w lp pt 7 lw 3 ti columnhead, \
       '' u (spread(2)):4 w lp pt 7 lw 3 ti columnhead, \
     for [i=5:*] '' u (spread(2)):i w lp pt 7 lw 1 ti columnhead
### end of script

Результат:

Добавление:

Немного более простой сценарий, если вы предполагаете фиксированное максимальное количество точек данных в день (здесь: c0=20).

Скрипт:

### spread data of one day over 24 hours
reset session

FILE = "SO78513320.csv"

set datafile separator comma
myFmt = "%Y/%m/%d"

set format x "%Y\n%m/%d" timedate
set offsets graph 0.05, graph 0.05, graph 0.05, graph 0.05
set key out
set grid x,y

c0 = 20   # max. datapoints per day
spread(col) = (t=timecolumn(col,myFmt), $0==0 ? (c=0, t1=t) : NaN, \
               t0=t1, t1=t, t0==t1 ? c=c+1 : c=0, t+86400.*c/c0)

plot FILE u (spread(2)):3 w lp pt 7 lw 3 ti columnhead, \
       '' u (spread(2)):4 w lp pt 7 lw 3 ti columnhead, \
     for [i=5:*] '' u (spread(2)):i w lp pt 7 lw 1 ti columnhead
### end of script

Результат:

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

Cwinte 22.05.2024 16:23

Что касается данных о времени: фактически у меня есть слот с номером 0–143 для 10-минутных сегментов в течение дня. Это добавляется к 1000 x целочисленному дню с тех пор, как я начал записывать данные, поэтому у меня есть timeID, целое число для компактности, но я могу ссылаться на таблицу информации о дне с текстом даты и несколькими другими соответствующими фактами о дне (например, вывод PVpanels , осадки, примечания)

Cwinte 22.05.2024 16:47

Еще многому предстоит научиться и усвоить то, что вы дали! Сеанс сброса, таблицы, почему $ в $Counts мне нужно оформить заказ и т. д. и т. п. Огромное спасибо... Метод распространения немного неправильно рисовал, когда точки данных не собирались из-за сбоев Интернета/ISP-сервера - таких было несколько. сбои в передаче данных.... Данные, использующие номер слота, будут в правильном месте. Я, конечно, могу установить c0 на 143!

Cwinte 22.05.2024 17:00

Я не уверен, как будет работать более простой код, в котором я усредняю ​​интервалы, чтобы получить меньше точек данных в день при построении графика более длительных периодов? [Но, возможно, это мое нынешнее невежество!] то есть, если я сохраню общий код сценария Gnuplot для использования для различных выходных данных sql, то количество точек данных в день будет меняться, но никогда не превысит 144 (от 0 до 143).

Cwinte 22.05.2024 17:08

На самом деле мне нужно построить гораздо больше рядов данных, около 20, и для большого количества SQL-запросов. Вызывается ли функция распространения(2) и запускается каждый раз, если да, то можно ли этого избежать, сохранив в таблице только один раз? Я знаю, что все серии должны иметь одинаковое количество считываний (если нет физического повреждения), даже если в идеале код Gnuplot не будет сообщен моим редактированием перед запуском, что это за число.

Cwinte 22.05.2024 17:18

Если немного поразмыслить, становится очевидным, что более простой код сожмет меньшее количество точек в первую часть дня... Документация по установленной таблице интересна, поэтому мы выводим результат в таблицу (я предполагаю, в памяти), а затем читаем это позже.

Cwinte 22.05.2024 17:40

@Cwinte, чтобы проверить, что может пойти не так, покажите пример данных, для которых сценарий «слегка неправильно рисует» данные. Функция spread() в первом примере предназначена именно для случая, если в день имеются точки данных переменного типа. Эти числа хранятся в блоке данных $Counts. В консоли gnuplot после запуска скрипта введите print $Counts, чтобы увидеть.

theozh 23.05.2024 16:00

Пока я ждал ответов, я пытался сделать больше в SQL. Мне удалось получить изменения дня только в столбце... но возникли проблемы, поскольку пробелы игнорировались, и Gnuplot брал данные из следующего столбца справа, что на некоторое время смутило меня. В конце концов я получил SQL, чтобы дать файл . когда дата была та же самая, и все было неплохо.

   # time based data, date text in column 2 while 1 is numeric of some kind (sorted but not user friendly)
    set term pdfcairo size 17in, 12in
    fdate=system("date +%F,%H.%M")
    set output sprintf('./sql2dyQRY%s.pdf', fdate)
    set key outside
    set size 0.98, 0.98
    set title "col2day SQLqry ".fdate font ",25";
    
    #plot first line heavier weight as clearer ref etc. Set y= (300) to position between my data areas
    plot  "sqlout.csv" using 1:(300):2 with labels rotate notitle, \
     "sqlout.csv" using 1:3 with lp lt 1 lw 3 title columnhead(3), \
     "sqlout.csv" using 1:4 with lp lt 2 lw 3 title columnhead(4), \
    for [col=5:*] "sqlout.csv" using 1:col with lp ls col title columnhead(col);
    unset output

выберите cast((timeID+(timeID%1000)*5.94)/30 как int) как "conTime", IIF(dayXS_date=LAG(dayXS_date)over(order by dayID),'.', dayXS_date) как dateLbl, cast(avg (IIF(locationID=1,AHx100/2,NULL)) как int) как "Ref-AHx", cast(avg(IIF(locationID=1,Cx10,NULL)) как int) как "Ref-Cx10", cast (avg(IIF(locationID=3,AHx100/2,NULL)) как int) как "Bed1-AH", cast(avg(IIF(locationID=7,AHx100/2,NULL)) как int) как "Bed2- AH", cast(avg(IIF(locationID=3,Cx10,NULL)) как int) как "Bed1-Cx10", cast(avg(IIF(locationID=7,Cx10,NULL)) как int) как "Bed2- Cx10" из истории, DayInfo, где timeID>193999 и dayID=cast(timeID/1000 as int) группируются по "conTime";

conTime  dateLbl     Ref-AHx  Ref-Cx10  Bed1-AH  Bed2-AH  Bed1-Cx10  Bed2-Cx10
-------  ----------  -------  --------  -------  -------  ---------  ---------
6466     2024/05/14  510      149       583      604      210        222
6467         .       510      147       587      601      210        221
6468         .       515      143       590      599      210        220
6469         .       515      144       582      597      209        220
6470         .       517      144       589      596      209        219

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

Другие вопросы по теме