Глядя на двоичный вывод из fortran на gnuplot
Итак, я создал двоичный файл с fortran, используя что-то похожее на это:
open (3,file=filename,form="unformatted",access="sequential")
write(3) matrix(i,:)
Как я понимаю, fortran помещает файл с 4 байтами на любом конце файла, а остальное-это только данные, которые я хочу (в этом случае список из 1000 двойников).
Я хочу прочитать это с помощью gnuplot, однако я не знаю, как заставить gnuplot пропустить первые и последние 4 байта, а остальные прочитать как двойные. Документация не очень полезна в этом рассматривать.
спасибо
3 ответов
тестирование с gnuplot 5.0, следующая fortran неформатированная запись данных двойного массива x
в размере N
,
open(FID,file='binaryfile')
do k = 1, N
write(FID) x(k)
end do
close(FID)
можно понять gnuplot со следующим:
plot 'binaryfile' binary format="%*1int%double%*1int"
The %*1int
означает, пропустить один раз четырехбайтовое целое число, эффективно пропуская данные верхнего и нижнего колонтитулов fortran обертывания вокруг вывода.
для получения дополнительной информации и экстраполяции для более сложных данных см. документы gnuplot 5.0 на двоичном файле и см. Размер форматы с, show datafile binary datasizes
. Обратите внимание, однако, что данные с несколькими столбцами (т. е. N двойников на запись) могут быть доступны в том же формате, что и выше, но как %Ndoubles
где N-целое число. Тогда с using 1:3
например, можно построить первый столбец против 3-го.
Andrew: я не вижу причин заставлять gnuplot обрабатывать эти дополнительные байты до/после ваших данных. Либо Fortran не делает эту прокладку, либо делает, и gnuplot обрабатывает ее без хлопот.
у меня была аналогичная проблема, и поиск Google всегда возвращал меня сюда. Я решил, что лучше опубликовать свое решение, если то же самое произойдет с другими людьми.
Я пытался сделать 2D-цветной график, используя файл "plot" gnuplot.dat 'matrix with image" команда. Мой код ASCII выходные файлы были слишком большими,поэтому я хотел использовать двоичные файлы. Я сделал примерно следующее:--3-->
в fortran:
implicit none
real, dimension(128,128) :: array
integer :: irec
! ... initialize array ...
inquire( iolength=irec ) array
open( 36, 'out.dat', form='unformatted', access='direct', recl=irec )
write( 36, rec=1 ) array
close( 36, status='keep' )
в gnuplot:
plot 'out.dat' binary array=128x128 format="%float" with image
Примечания:
по умолчанию gnuplot предполагает единую точность в двоичных файлах. Если ваш выходы программы fortran в двойной точности, просто изменяют " % float" удваивать."
моя программа использовала данные двойной точности в массиве, но исходящие файлы быть слишком большой. Поскольку изображения, основанные на двойной или одиночной точности неразличимы для глаз, и файлы данных двойной точности большой, я преобразовал данные двойной точности в данные с одной точностью перед записью в файл.
возможно, вам придется адаптировать команду gnuplot в зависимости от того, что вы хотите сделать с Матрицей, но это загружает ее и строит ее что ж. Это сделало то, что мне было нужно, и я надеюсь, что это поможет кому-нибудь
еще кто подобная проблема.Как вы можете видеть, если Fortran добавляет дополнительные байты до / после ваших данных, gnuplot, похоже, читает данные, не заставляя вас принимать эти дополнительные байты в счет.
может быть проще использовать прямой ввод-вывод вместо последовательного:
inquire (iolength = irec) matrix(1,:) !total record length for a row
open (3, file=filename, form="unformatted", access="direct", recl=irec)
write(3, rec=1) matrix(i,:)
на inquire
оператор дает вам длину выходного списка в единицах "recl". Таким образом, весь список помещается в одну запись длины irec
.
для записи матрицы в файл по столбцу вы можете сделать:
inquire (iolength = irec) matrix(:,1)
open (3, file=filename, form="unformatted", access="direct", recl=irec)
do i=1,ncol
write(3, rec=i) matrix(:,i)
end do
или row-wise:
inquire (iolength = irec) matrix(1,:)
open (3, file=filename, form="unformatted", access="direct", recl=irec)
do i=1,nrow
write(3, rec=i) matrix(i,:)
end do
или поэлементного:
inquire (iolength = irec) matrix(1,1)
open (3, file=filename, form="unformatted", access="direct", recl=irec)
do j=1,ncol
do i=1,nrow
write(3, rec=j+(ncol-1)*i) matrix(i,j)
end do
end do
или сбросить всю матрицу:
inquire (iolength = irec) matrix
open (3, file=filename, form="unformatted", access="direct", recl=irec)
write(3, rec=1) matrix