Я пытаюсь использовать gnuplot 5.0 для построения 2D-массива данных без полей, границ или осей ... просто 2D-изображение (.png или .jpg), представляющее некоторые данные. Я хотел бы иметь каждый элемент массива соответствует ровно один пиксель изображения с не масштабирования / интерполяции и т.д. , и без каких - либо дополнительных белых пикселей по краям.
До сих пор, когда я пытаюсь установить поля равными 0 и даже используя pixels
флаг, у меня все еще остается ряд белых пикселей справа и сверху границ изображения.
Как я могу получить только файл изображения с попиксельным представлением массива данных и ничего лишнего?
скрипт gnuplot:
#!/usr/bin/gnuplot --persist
set terminal png size 400, 200
set size ratio -1
set lmargin at screen 0
set rmargin at screen 1
set tmargin at screen 0
set bmargin at screen 1
unset colorbox
unset tics
unset xtics
unset ytics
unset border
unset key
set output "pic.png"
plot "T.dat" binary array=400x200 format="%f" with image pixels notitle
Пример данных из Фортрана 90:
program main
implicit none
integer, parameter :: nx = 400
integer, parameter :: ny = 200
real, dimension (:,:), allocatable :: T
allocate (T(nx,ny))
T(:,:)=0.500
T(2,2)=5.
T(nx-1,ny-1)=5.
T(2,ny-1)=5.
T(nx-1,2)=5.
open(3, file="T.dat", access="stream")
write(3) T(:,:)
close(3)
end program main
x y z
формате списка?Ответы:
Некоторые терминалы gnuplot реализуют «с изображением» путем создания отдельного файла png, содержащего изображение, а затем ссылки на него внутри полученного графика. Непосредственное использование этого отдельного файла изображения png позволит избежать проблем с макетом страницы, полями и т. Д. Здесь я использую терминал canvas. Сам сюжет выброшен; все, что мы храним - это файл png, созданный с нужным содержимым.
источник
set term tikz externalimages
и тот же трюк, и этот терминал сбрасывает счетчик при каждом «заданном сроке». Вы не можете использоватьset output "/dev/null"
с tikz, но если это не сработает, чтобы подавить вывод для вас, то вам может быть все равно. Терминалы tkcanvas и svg - это другие возможности, но внешний механизм png зависит от версии gnuplot и параметров компиляции.Не используйте gnuplot.
Вместо этого напишите скрипт, который читает ваши данные и конвертирует их в один из форматов Portable Anymap . Вот пример в Python:
Если вы можете изменить программу, которая генерирует файл данных, вы можете даже пропустить вышеуказанный шаг и вместо этого сгенерировать данные непосредственно в формате PNM.
В любом случае, вы можете использовать ImageMagick для преобразования изображения в формат по вашему выбору:
источник
imwrite
функция может использоваться для сохранения 2D-данных в виде изображения PNG.gnuplot
, то я просто буду использоватьmatplotlib
вместо этого (см. Мой ответ ниже). Это большой вклад, но технически вопрос / щедрость требуетgnuplot
решения, столь же непригодного, как кажется, для этой конкретной задачи.Это должно быть легкой задачей, однако, по-видимому, это не так. Следующее может быть (громоздким) решением, потому что все другие попытки потерпели неудачу. Я подозреваю, что в некоторой графической библиотеке есть проблема, которую вы, вероятно, не можете решить как пользователь gnuplot.
Вы упомянули, что данные матрицы ASCII тоже в порядке. «Хитрость» здесь в том, чтобы построить данные,
with lines
где данные «прерываются» пустыми линиями, в основном рисуя отдельные точки. Отметьте это на тот случай, если вам нужно поместить ваш файл данных 1: 1 в блок данных .Однако, если это не так уже достаточно странно, кажется, работают для
png
иgif
терминала , но не дляpngcairo
илиwxt
. Я думаю, что обходной путь, вероятно, медленный и неэффективный, но по крайней мере он создает желаемый результат. Я не уверен, есть ли ограничение по размеру. Протестировано с разрешением 100х100 точек на Win7, gnuplot 5.2.6. Комментарии и улучшения приветствуются.Код:
Результат: (100x100 пикселей)
(увеличено на черном фоне):
Изображение с разрешением 400x200 пикселей (на моем 8-летнем ноутбуке это занимает около 22 секунд).
источник
x
иy
. Это все еще работает, еслиSizeX
иSizeY
не равны. Я исправлю код.Data2
?То, что я на самом деле использовал, чтобы получить то, что мне было нужно, хотя вопрос / награда требует
gnuplot
решения:matplotlib
имеет функцию matplotlib.pyplot.imsave, которая делает то, что я искал ... то есть вывод «просто пикселей данных» и никаких дополнительных функций, таких как границы, поля, оси и т. д. Изначально я знал только о matplotlib.pyplot.imshow и должен был тянуть много трюков , чтобы устранить все дополнения из файла изображения и предотвратить любые интерполяции / сглаживание и т.д. (и поэтому обратились кgnuplot
в определенной точке). Сimsave
довольно легко, поэтому я вернулся к использованиюmatplotlib
для простого , но по- прежнему гибких (с точкой зрения палитры, масштабирования и т.д.) решений для «пиксела точного» участков. Вот пример:источник
Хорошо, вот другое возможное решение (я отделил его от моего первого громоздкого подхода). Это создает сюжет сразу, менее чем за секунду. Нет необходимости переименования или создания бесполезного файла.
Я думаю, ключом является использование
term png
иps 0.1
.У меня нет доказательств, но я думаю, что
ps 1
было бы ок. 6 пикселей большого размера и создаст некоторое перекрытие и / или белые пиксели в углу. Опять же, по какой-то причине он работает,term png
но не работаетterm pngcairo
.Я протестировал (Win7, gnuplot 5.2.6) бинарный файл с
00 00 FF
повторяющимся шаблоном (здесь я не могу отображать нулевые байты). Поскольку gnuplot, по-видимому, читает 4 байта на элемент массива (format="%d"
), это приводит к чередующемуся шаблону RGB, если я строю графикwith lc rgb var
.Таким же образом (надеюсь) мы можем понять, как читать
format="%f"
и использовать его вместе с цветовой палитрой. Я думаю, это то, что вы ищете, верно? Дальнейшие результаты испытаний, комментарии, улучшения и объяснения приветствуются.Код:
Результат:
источник