Estoy tratando de usar gnuplot 5.0 para trazar una matriz de datos 2D sin márgenes, bordes o ejes ... solo una imagen 2D (.png o .jpg) que representa algunos datos. Me gustaría tener cada elemento de la matriz para corresponder exactamente a un píxel de la imagen con ninguna escala / interpolación , etc y no hay píxeles blancos adicionales en los bordes.
Hasta ahora, cuando trato de establecer los márgenes en 0 e incluso usando la pixels
bandera, todavía me queda una fila de píxeles blancos en los bordes derecho e superior de la imagen.
¿Cómo puedo obtener solo un archivo de imagen con representación píxel por píxel de una matriz de datos y nada más?
script 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
Datos de ejemplo de 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
formato de lista?Respuestas:
Algunos terminales gnuplot implementan "con imagen" al crear un archivo png separado que contiene la imagen y luego vincularlo dentro del gráfico resultante. Usar ese archivo de imagen png por separado directamente evitará cualquier problema de diseño de página, márgenes, etc. Aquí uso el terminal de lienzo. La trama en sí es desechada; todo lo que guardamos es el archivo png creado con el contenido deseado.
fuente
set term tikz externalimages
y ese terminal restablece el contador en cada "término establecido". No se puede usarset output "/dev/null"
con tikz, pero si eso no funciona para suprimir la salida para usted, entonces puede que no le importe. Los terminales tkcanvas y svg son otras posibilidades, pero el mecanismo png externo depende de la versión de gnuplot y las opciones de compilación.No uses gnuplot.
En su lugar, escriba un script que lea sus datos y los convierta en uno de los formatos Portable Anymap . Aquí hay un ejemplo en Python:
Si puede modificar el programa que genera el archivo de datos, incluso puede omitir el paso anterior y en su lugar generar los datos directamente en un formato PNM.
De cualquier manera, puede usar ImageMagick para convertir la imagen al formato que elija:
fuente
imwrite
función se puede usar para guardar datos 2D como una imagen PNG.gnuplot
, entonces solo lamatplotlib
usaré (vea mi respuesta a continuación). Esta es una gran contribución, pero técnicamente la pregunta / recompensa pide unagnuplot
solución, tan inadecuada como parece ser para esta tarea en particular.Esto debería ser una tarea fácil, sin embargo, aparentemente no lo es. Lo siguiente podría ser una solución (engorrosa) porque todos los demás intentos fallaron. Sospecho que algunas bibliotecas de gráficos tienen un problema que probablemente no pueda resolver como usuario de gnuplot.
Usted mencionó que los datos de la matriz ASCII también están bien. El "truco" aquí es trazar los datos
with lines
donde los datos son "interrumpidos" por líneas vacías, básicamente dibujando puntos únicos. Verifique esto en caso de que necesite obtener su archivo de datos 1: 1 en un bloque de datos .Sin embargo, si aún no es lo suficientemente extraño, parece funcionar para
png
ygif
terminal pero no parapngcairo
owxt
. Supongo que la solución es probablemente lenta e ineficiente, pero al menos crea el resultado deseado. No estoy seguro de si hay un límite de tamaño. Probado con 100x100 píxeles con Win7, gnuplot 5.2.6. Comentarios y mejoras son bienvenidos.Código:
Resultado: (100x100 píxeles)
(ampliado con fondo negro):
Imagen con 400x200 píxeles (toma alrededor de 22 segundos en mi computadora portátil de 8 años).
fuente
x
yy
. Todavía funciona siSizeX
ySizeY
no son iguales. Corregiré el código.Data2
?Lo que terminé usando en realidad para obtener lo que necesitaba a pesar de que la pregunta / recompensa pide una
gnuplot
solución:matplotlib
tiene una función matplotlib.pyplot.imsave que hace lo que estaba buscando ... es decir, trazar 'solo píxeles de datos' y sin extras como bordes, márgenes, ejes, etc. Originalmente solo sabía sobre matplotlib.pyplot.imshow y tuve que Realice muchos trucos para eliminar todos los extras del archivo de imagen y evitar cualquier interpolación / suavizado, etc. (y, por lo tanto,gnuplot
en un determinado punto). Conimsave
esto es bastante fácil, así que vuelvo a usarmatplotlib
una solución fácil pero flexible (en términos de mapa de colores, escala, etc.) para gráficos 'exactos de píxeles'. Aquí hay un ejemplo:fuente
OK, aquí hay otra posible solución (la separé de mi primer enfoque engorroso). Crea la trama de inmediato, menos de un segundo. No es necesario renombrar ni crear un archivo inútil.
Supongo que la clave es usar
term png
yps 0.1
.No tengo una prueba pero creo
ps 1
que sería ca. 6 píxeles de gran tamaño y crearían algunos solapamientos y / o píxeles blancos en la esquina. Nuevamente, por alguna razón parece funcionarterm png
pero no conterm pngcairo
.Lo que probé (Win7, gnuplot 5.2.6) es un archivo binario que tiene el patrón
00 00 FF
repetido por todas partes (no puedo mostrar bytes nulos aquí). Dado que gnuplot aparentemente lee 4 bytes por elemento de matriz (format="%d"
), esto conduce a un patrón RGB alternativo si estoy tramandowith lc rgb var
.De la misma manera (con suerte) podemos descubrir cómo leerlo
format="%f"
y usarlo junto con una paleta de colores. Supongo que eso es lo que estás buscando, ¿verdad? Otros resultados de la prueba, comentarios, mejoras y explicaciones son bienvenidos.Código:
Resultado:
fuente