
Tengo un documento con algunas imágenes de TikZ, que se generan automáticamente a partir de un programa que he escrito. Todas las imágenes son bastante similares y cada una de ellas contiene una gran cantidad de cuadrados con colores rgb diferentes y arbitrarios. Mi pregunta es:¿Cuál es la mejor manera de colorear toda esta gran cantidad de cuadrados?
El método que he utilizado hasta ahora consiste en definir el color fillcolor
mediante la macro \definecolor
, antes de dibujar cada cuadrado, y utilizar ese color para rellenar el cuadrado. Eso significa que cada vez que dibujo un cuadrado nuevo, lo defino fillcolor
nuevamente.
Sin embargo, no estoy tan seguro de que esa sea la forma de hacerlo. pdflatex parece requerir mucha memoria al compilar el documento y, por alguna extraña razón, se queda sin memoria si incluyo más de 5 imágenes (incluso si aumento diez veces la cantidad de memoria al pasar de 5 a 6 imágenes) . ¿Existe alguna posibilidad de que almacene todos los colores que he definido y que deba hacer que pdflatex se "olvide" fillcolor
antes de \definecolor
volver a llamar?
Actualizar:A continuación se muestra un ejemplo de una de las imágenes de TikZ que quiero en mi documento (es una visualización del campo de fracción de fase en una simulación de fluido de dos fases usando el método de volumen finito y el método de volumen de fluido, y sí, lo sé, el la interfaz fluida no es exactamente nítida):
Esta imagen en particular consta de 1990 cuadrados llenos y 4 cuadrados vacíos.
Primero, para cada cuadrado, fillcolor
se define con \definecolor
y el cuadrado se rellena con ese color:
\definecolor{fillcolor}{rgb}{1.000000,0.241735,0.000000}
\fill[fillcolor] (0.203125,0.578125) rectangle (0.218750,0.593750);
Luego se dibujan los lados de cada cuadrado, por ejemplo.
\draw (0.203125,0.578125) rectangle (0.218750,0.593750);
Respuesta1
Como dije en un comentario, si \definecolor
simplemente almacena la definición de color en una macro TeX, al redefinirla se reciclará la misma macro y, por lo tanto, no se utilizará más memoria.
Sin embargo, también es posible que \defincolor
esté enviando algún tipo de código PDF literal que defina el color para el motor PDF. En este caso, hasta donde tengo entendido, tampoco se debería utilizar más memoria para redefinir muchas veces el mismo color.
De todos modos, por si acaso, es posible utilizar un color RGB sin definición previa. Aquí es cómo.
En principio,
tikz
reconoce una especificación de color de la forma{rgb:red,255;green,255;blue:255}
. Pero no se interpreta como cabría esperar. Por ejemplo,[fill={rgb:red,255;green,255;blue,0}]
no producirá amarillo, sino un amarillo teñido de negro (consulte la figura siguiente). No pude encontrar documentación sobre cómo funciona esta especificación. Aparentemente se suman todos los valores y luego cada valor particular se divide por elred
totalgreen
.blue
Es decir, lo que especificamos no son valores de bytes absolutos, sino pesos relativos. Entonces, para obtener amarillo podemos escribir:{rgb:red,1;green:1;blue:-1}
. Esta sintaxis me parece bastante inconveniente (además, ¿cómo podríamos volvernos "blancos"?)PGF utiliza una macro interna:
\pgfsys@color@rgb@fill
que tiene el comportamiento esperado. Recibe tres valores numéricos para los componentes yr
, como valores de 0 a 255. Entonces podemos usar esta macro para establecer el color de relleno justo antes del comando de relleno.g
b
Aquí hay un código que muestra varias opciones:
\documentclass{article}
\usepackage{tikz}
% Define a more convenient macro without @ in its name
\makeatletter
\def\fillRGB#1#2#3{\pgfsys@color@rgb@fill{#1}{#2}{#3}}
\makeatother
\begin{document}
% Standard xcolor defined color
\definecolor{RGByellow}{RGB}{255,255,0}
% Some examples
\tikz{\node[draw,fill=RGByellow]{defined colour};}
\tikz{\node[draw,fill={rgb:red,255;green,255;blue,0}]{Tikz rgb: 255,255,0};}
\tikz{\node[draw,fill={rgb:red,1;green,1;blue,-1}]{Tikz rgb: 1,1,-1};}
\tikz{\fillRGB{255}{255}{0}\node[fill,draw]{{\tt fillRGB: 255,255,0} };}
\end{document}
El resultado:
Respuesta2
Creo que tu enfoque \definecolor
está bien.
Mi sugerencia sería utilizar la capa básica PGF en lugar de tikz, es decir, utilizar algo como
\definecolor{fillcolor}{...}
\pgfsetfillcolor{fillcolor}
\pgfsetstrokecolor{fillcolor!80!black}
\pgfpathrectangle{...}{...}
\pgfusepathqfillstroke
% next one, no scope in-between...
\definecolor{fillcolor}{...}
\pgfsetfillcolor{fillcolor}
\pgfsetstrokecolor{fillcolor!80!black}
\pgfpathrectangle{...}{...}
\pgfusepathqfillstroke
Busque los comandos mencionados en pgfmanual.pdf, ya que es posible que haya escrito mal algunos de ellos (los cité de memoria).
Mi sugerencia de combinar trazo y relleno y variar solo el color podría tener sentido para usted y también podría aplicarse al trazado tikz. Esto también debería reducir el consumo de memoria y el tiempo de composición tipográfica.
Un comentario que en realidad está fuera del alcance de su pregunta: mi sugerencia de usar el color de dibujo fillcolor!80!black
está inspirada en el valor predeterminado pgfplots
que encuentro menos duro en comparación con los contornos negros. Y pgfplots tiene el mismo caso de uso que aquí: lo que escribe aquí es en realidad una especie de malla/superficie con sombreado facetado y entrada de color explícita (en pgfplots:\addplot3[surf]
comparepgfplots: colorea una navegación (3D) usando colores RGB arbitrarios).
Incluso después de la reducción de memoria, tiene "muchos" puntos de datos (hablando en términos de lo que se supone que debe manejar TeX). Por lo tanto, incluso reducir la memoria podría llegar eventualmente a los límites de TeX. Si una imagen funciona pero más de una falla, puede beneficiarse del uso de la externalización de imágenes. También puede beneficiarse del uso lualatex
en lugar de pdflatex
la lualatex
asignación de memoria dinámica. También deberías experimentar con \clearpage
entre adyacentes.figure
para asegurarte de que TeX no tenga cifras antiguas en su memoria (como sugirió @JLDiaz en un comentario). Los detalles sobre la externalización de imágenes y el consumo de memoria se resumen en la sección "Consideraciones sobre memoria y velocidad" enhttp://pgfplots.sourceforge.net/pgfplots.pdf
Respuesta3
Para crear un sombreado suave y sencillo entre rojo y azul (a través de naranja, amarillo, verde y cian), puede utilizar el Hsb
modelo de color (proporcionado en el xcolor
paquete):
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,...,9}{
\foreach \y in {0,...,9}{
\pgfmathtruncatemacro{\myhue}{(\y*10+\x)*2.5}
\definecolor{col}{rgb:Hsb}{\myhue,1,1}
\draw[fill=col] (\x,\y) rectangle ++(1,1);
}
}
\end{tikzpicture}
\end{document}
O (con otra sintaxis):
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\colorlet{redhsb}[hsb]{red}%
\colorlet{bluehsb}[hsb]{blue}%
\foreach \x in {0,...,9}{
\foreach \y in {0,...,9}{
\pgfmathtruncatemacro{\rat}{\y*10+\x}
\colorlet{col}[rgb]{bluehsb!\rat!redhsb}
\draw[fill=col] (\x,\y) rectangle ++(1,1);
}
}
\end{tikzpicture}
\end{document}
Este método se puede utilizar con una gran cantidad de cuadrados pequeños (aquí, 100 x 100):
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\colorlet{redhsb}[hsb]{red}%
\colorlet{bluehsb}[hsb]{blue}%
\foreach \x in {0,...,100}{
\foreach \y in {0,...,100}{
\pgfmathtruncatemacro{\rat}{(cos(\x*4)+sin(\y*4))*25+50}
\colorlet{col}[rgb]{bluehsb!\rat!redhsb}
\draw[fill=col,line width=.1pt] (\x*.1,\y*.1) rectangle ++(.1,.1);
}
}
\end{tikzpicture}
\end{document}