Можно ли читать данные из файла в массив gnuplot?

Есть ли способ загрузить данные из файла в массив Gnuplot? Я работаю с программой, которая предоставляет данные и вызывает gnuplot для создания графика. Теперь я пытаюсь установить xrange, чтобы установить верхний предел, когда данные во втором столбце наконец приближаются к нулю. Я много гуглил и пробовал разные методы. К сожалению безуспешно. Мне кажется, что наиболее многообещающим, но все еще не работающим подходом является импорт данных и их сохранение в массиве. Выдержка из кода приведена ниже:

stats '<datafile>' using 1:($2/1000.) nooutput
array myarray[STATS_records]
do for [i=STATS_records:0:-1] {
  stats '<datafile>' using 1:($2/1000.) index i nooutput
  myarray[i] = STATS_min_y
}

Выражение статистики в цикле вызывает ошибку, поскольку значения не найдены. Заранее благодарим вас за ваши предложения или альтернативные решения.

Добро пожаловать в StackOverflow! Как выглядят ваши данные? Хорошо, два столбца, но есть ли в нем пустые строки или двойные пустые строки? Пожалуйста, опишите структуру вашего файла данных и приведите свернутый пример. Кроме того, похоже, вы хотите изменить порядок данных, верно?

theozh 10.05.2023 14:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Из вашего текущего заголовка вопроса и фрагмента кода я предполагаю, что вы хотите прочитать данные, перевернутые в массив.

Теперь я пытаюсь установить xrange, чтобы установить верхний предел, когда данные во втором столбце наконец приближаются к нулю.

Это предложение заставляет меня думать, что, возможно, есть что-то еще, что вы не показываете и что может быть решено и без массивов. Может быть, мы столкнулись с xy-проблемой?

Следующий сценарий считывает столбец файла данных, преобразованный в массив.

Данные: SO76218289.dat

 1    1.0
 2    2.1
 3    3.2
 4    4.3
 5    5.4
 6    6.5
 7    7.6
 8    8.7
 9    9.8
10   10.9

Скрипт: (требуется gnuplot>=5.2.0)

### read data from file reversed into array
reset session

FILE = "SO76218289.dat"

stats FILE u 0 nooutput     # get number of rows
rowCount = STATS_records
array A[rowCount]           # set array size

stats FILE u (A[int(rowCount-$0)] = $2) nooutput

print A
### end of script

Результат:

[10.9,9.8,8.7,7.6,6.5,5.4,4.3,3.2,2.1,1.0]

Добавление:

На самом деле, это была небольшая проблема с xy: вы просили поместить данные в массив, но фактическая цель состояла в том, чтобы ограничить диапазон x диапазоном, где y>0. Это можно сделать проще. Используя тернарный оператор (отметьте help ternary), значения x будут установлены на NaN, если y<0. Значение NaN не будет отображаться и учитываться для x-autorange. Следовательно, в приведенном ниже примере диапазон x автоматически ограничивается [3:7]. Если значения y могут стать ниже нуля в пределах ограниченного диапазона, а вы, тем не менее, хотите, чтобы линии были сведены к нулю, сценарий необходимо адаптировать.

Скрипт:

### limit xrange to data y>0
reset session

$Data <<EOD
 1   -1.0
 2   -0.5
 3    0.5
 4    3.0
 5    2.0
 6    1.0
 7    0.5 
 8   -0.1
 9   -0.5
10   -1.0
EOD

plot $Data u ($2>0 ? $1 : NaN):2 w lp pt 7 lc "red" notitle
### end of script

Результат:

Дополнение 2:

Просто для иллюстрации вы также можете ограничить данные диапазоном x, где y>0, включая первую последовательность значений Ny<=0. Для этого требуется stats и более сложный оператор для понимания с использованием тернарных операторов и последовательной оценки (отметьте help operators binary). Окончательное ограничение будет сделано every (отметьте help every).

Скрипт:

### limit x-range to values with y>0 and N values y<=0
reset session

$Data <<EOD
 1   -1.0
 2   -0.5
 3    0.5
 4    3.0
 5    2.0
 6    1.0
 7    0.5 
 8    0.0
 9    0.0
10    0.0
11   -1.0
12   -2.0
EOD

N  = 3             # max. number of y-values <0 in a sequence
n0 = n1 = NaN
c  = 0
stats $Data u ($2>0 && n0!=n0 ? n0=$0 : $2<=0 && n0==n0 && n1!=n1 ? c=c+1 : c=0, c==N ? n1=$0 : 0) nooutput
print n0,n1

plot $Data u 1:2 every ::n0::n1 w lp pt 7 lc "red"
### end of script

Некоторые пояснения:

  • сначала n0 и n1 инициализируются как NaN и c=0.

Каково значение:

($2>0 && n0!=n0 ? n0=$0 : $2<=0 && n0==n0 && n1!=n1 ? c=c+1 : c=0, c==N ? n1=$0 : 0)
  • если y>0 и n0 равно NaN (см. gnuplot: как сравнить с NaN?), то установите n0 на текущий индекс строки $0, который будет в первый раз y>0.
  • иначе, если y<=0 и n0 не NaN, а n1 равно NaN, увеличьте счетчик c на 1, иначе сбросьте счетчик на c=0.
  • если c равно N, установите n1 на текущий индекс строки $0.

В итоге: n0 содержит индекс строки с первым временем y>0, а n1 содержит индекс строки, когда y было N-кратно <=0 (но только после того, как n0 было установлено какое-то значение). Когда вы рисуете данные, вы просто ограничиваете их с помощью every ::n0::n1.

В примере диапазон x будет ограничен [3:10], поскольку последние N=3 значения y равны y<=0.

Результат:

Спасибо за ваше дополнение. Это кажется гораздо более простым решением, и оно очень полезно. Вы, вероятно, правы, что это была проблема xy в определенной степени. Я постараюсь избежать этой ошибки в будущем. Тем не менее, мне кажется, что мое решение предлагает больше гибкости. Например, если я хочу включить первые n значений, которые равны нулю. Однако мне, возможно, придется больше работать с тернарными операторами, чтобы лучше понять их и их возможности.

Manuel Hochheim 12.05.2023 07:56

@ManuelHochheim да, тернарные операторы часто очень полезны. Ваша (новая) задача по отображению первых n нулевых значений также может быть выполнена без массивов (с stats и некоторым счетчиком). Но я согласен, массивы тоже могут быть полезны во многих случаях.

theozh 12.05.2023 08:18

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

FILE = '<datafile>'

stats FILE u 0 nooutput

rowCount = STATS_records

array A[rowCount]

stats FILE u (A[int(rowCount-$0)] = $2) nooutput

do for [i=1:rowCount-1] {
  if (int(A[i]) > 0) {
     xoffset = rowCount - i
     break
  }
}

stats '<datafile>' u 1:($2/1000) nooutput
xmin = STATS_min_x
xmax = STATS_min_x + xoffset

# Set ranges and ticks
set xrange [xmin:xmax]

plot '<datafile>' using 1:($2/1000.)

В своем коде я пытаюсь найти точку, в которой мой столбец данных просто содержит нулевые значения. Он соответствующим образом регулирует xrange. Это работает для меня. Но если вы знаете лучшую версию, пожалуйста, дайте мне знать. Я был бы рад учиться у вас и улучшать свои навыки работы с gnuplot.

Итак, я немного лучше понимаю, что вы на самом деле хотите сделать. Но все еще нужны некоторые догадки, как я теперь понимаю: у вас есть некоторые данные, и вы хотите ограничить xrange так, чтобы значения y превышали 0, верно? Что, если значения y окажутся ниже и выше нуля несколько раз?

theozh 10.05.2023 17:10

Это правильно, что я хочу ограничить диапазон x таким образом, чтобы значения y в хвосте моих данных были больше 0. Значения меньше нуля в моем случае не имеют значения, поскольку я знаю, что мои значения всегда больше равны нулю.

Manuel Hochheim 12.05.2023 07:53

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