¿Cómo utilizar una gran cantidad de colores rgb arbitrarios en una imagen TikZ?

¿Cómo utilizar una gran cantidad de colores rgb arbitrarios en una imagen TikZ?

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 fillcolormediante 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 fillcolornuevamente.

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" fillcolorantes de \definecolorvolver 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):

Imagen de TikZ que contiene 1990 cuadrados de diferentes colores.

Esta imagen en particular consta de 1990 cuadrados llenos y 4 cuadrados vacíos.

Primero, para cada cuadrado, fillcolorse define con \definecolory 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 \definecolorsimplemente 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 \defincoloresté 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, tikzreconoce 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 el redtotal green. blueEs 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@fillque tiene el comportamiento esperado. Recibe tres valores numéricos para los componentes y r, como valores de 0 a 255. Entonces podemos usar esta macro para establecer el color de relleno justo antes del comando de relleno.gb

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:

Resultado

Respuesta2

Creo que tu enfoque \definecolorestá 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!blackestá inspirada en el valor predeterminado pgfplotsque 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 lualatexen lugar de pdflatexla lualatexasignación de memoria dinámica. También deberías experimentar con \clearpageentre 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 Hsbmodelo de color (proporcionado en el xcolorpaquete):

\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}

ingrese la descripción de la imagen aquí

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}

ingrese la descripción de la imagen aquí

información relacionada