Saya mencoba menggunakan gnuplot 5.0 untuk memplot data 2D array tanpa margin atau batas atau sumbu ... hanya gambar 2D (.png atau .jpg) yang mewakili beberapa data. Saya ingin memiliki setiap elemen array untuk berkorespondensi dengan tepat satu pixel dalam gambar dengan tidak ada skala / interpolasi dll dan tidak ada piksel ekstra putih di tepi.
Sejauh ini, ketika saya mencoba mengatur margin ke 0 dan bahkan menggunakan pixels
bendera, saya masih tersisa dengan deretan piksel putih di kanan dan batas atas gambar.
Bagaimana saya bisa mendapatkan hanya file gambar dengan representasi pixel-by-pixel dari array data dan tidak ada tambahan?
skrip 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
Contoh data dari Fortran 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
format daftar?Jawaban:
Beberapa terminal gnuplot menerapkan "dengan gambar" dengan membuat file png terpisah berisi gambar dan kemudian menautkannya di dalam plot yang dihasilkan. Menggunakan file gambar png yang terpisah secara langsung akan menghindari masalah tata letak halaman, margin, dll. Di sini saya menggunakan terminal kanvas. Plot itu sendiri dibuang; yang kami simpan hanyalah file png yang dibuat dengan konten yang diinginkan.
sumber
set term tikz externalimages
dan bahwa terminal me-reset penghitung pada setiap "istilah yang ditetapkan". Anda tidak dapat menggunakanset output "/dev/null"
dengan tikz, tetapi jika itu tidak berhasil untuk menekan output untuk Anda maka Anda mungkin tidak peduli. Terminal tkcanvas dan svg adalah kemungkinan lain, tetapi mekanisme png eksternal pada mereka tergantung pada versi gnuplot dan opsi kompilasi.Jangan gunakan gnuplot.
Alih-alih, tulis skrip yang membaca data Anda dan mengubahnya menjadi salah satu format Portable Anymap . Berikut ini contoh dalam Python:
Jika Anda dapat memodifikasi program yang menghasilkan file data, Anda bahkan dapat melewatkan langkah di atas dan menghasilkan data secara langsung dalam format PNM.
Apa pun itu, Anda kemudian dapat menggunakan ImageMagick untuk mengonversi gambar ke format pilihan Anda:
sumber
imwrite
Fungsi ini dapat digunakan untuk menyimpan data 2D sebagai gambar PNG.gnuplot
, maka saya hanya akan menggunakanmatplotlib
(lihat jawaban saya di bawah). Ini adalah kontribusi yang besar, tetapi secara teknis pertanyaan / karunia memintagnuplot
solusi, tidak layak seperti yang tampaknya untuk tugas khusus ini.Ini seharusnya menjadi tugas yang mudah, namun ternyata tidak. Berikut ini mungkin solusi (rumit) karena semua upaya lainnya gagal. Kecurigaan saya adalah bahwa beberapa perpustakaan grafis memiliki masalah yang mungkin tidak dapat Anda selesaikan sebagai pengguna gnuplot.
Anda menyebutkan bahwa data matriks ASCII juga ok. "Trik" di sini adalah memplot data di
with lines
mana data "terputus" oleh garis kosong, pada dasarnya menggambar titik tunggal. Periksa ini jika Anda perlu memasukkan datafile 1: 1 Anda ke datablock .Namun, jika itu belum cukup aneh, tampaknya berfungsi
png
dangif
terminal tetapi tidak untukpngcairo
atauwxt
. Saya kira solusinya mungkin lambat dan tidak efisien tetapi setidaknya itu menciptakan output yang diinginkan. Saya tidak yakin apakah ada batasan ukuran. Diuji dengan 100x100 piksel dengan Win7, gnuplot 5.2.6. Komentar dan peningkatan dipersilahkan.Kode:
Hasil: (100x100 piksel)
(diperbesar dengan latar belakang hitam):
Gambar dengan 400x200 piksel (membutuhkan sekitar 22 detik pada laptop saya yang berusia 8 tahun).
sumber
x
dany
. Ini masih berfungsi jikaSizeX
danSizeY
tidak sama. Saya akan memperbaiki kodenya.Data2
?Apa yang akhirnya saya gunakan untuk mendapatkan apa yang saya butuhkan meskipun pertanyaan / karunia meminta
gnuplot
solusi:matplotlib
memiliki fungsi matplotlib.pyplot.imsave yang melakukan apa yang saya cari ... yaitu merencanakan 'hanya data piksel' dan tidak ada tambahan seperti batas, margin, sumbu, dll. Awalnya saya hanya tahu tentang matplotlib.pyplot.imshow dan harus tarik banyak trik untuk menghilangkan semua ekstra dari file gambar dan mencegah interpolasi / smoothing dll (dan karena itu beralih kegnuplot
titik tertentu). Denganimsave
ini cukup mudah, jadi saya kembali menggunakanmatplotlib
untuk solusi yang mudah namun tetap fleksibel (dalam hal colormap, penskalaan, dll) untuk plot 'pixel tepat'. Ini sebuah contoh:sumber
OK, inilah solusi lain yang mungkin (saya memisahkannya dari pendekatan rumit pertama saya). Itu membuat plot segera, kurang dari satu detik. Tidak perlu mengganti nama atau membuat file yang tidak berguna.
Saya kira kuncinya adalah menggunakan
term png
danps 0.1
.Saya tidak punya bukti tapi saya pikir
ps 1
akan ca. 6 piksel besar dan akan membuat beberapa piksel tumpang tindih dan / atau putih di sudutnya. Sekali lagi, untuk alasan apa pun tampaknya bekerja denganterm png
tetapi tidak denganterm pngcairo
.Apa yang saya uji (Win7, gnuplot 5.2.6) adalah file biner yang memiliki pola yang
00 00 FF
berulang (saya tidak bisa menampilkan byte nol di sini). Karena gnuplot ternyata membaca 4 byte per item array (format="%d"
), ini mengarah ke pola RGB bergantian jika saya merencanakanwith lc rgb var
.Dengan cara yang sama (semoga) kita bisa mengetahui cara membaca
format="%f"
dan menggunakannya bersama dengan palet warna. Saya kira itu yang Anda cari, kan? Hasil tes lebih lanjut, komentar, perbaikan dan penjelasan dipersilahkan.Kode:
Hasil:
sumber