
Ich habe ein Dokument mit einigen TikZ-Bildern, die automatisch von einem von mir geschriebenen Programm generiert werden. Alle Bilder sind ziemlich ähnlich und jedes von ihnen enthält eine große Anzahl von Quadraten mit unterschiedlichen, beliebigen RGB-Farben. Meine Frage ist:Wie kann ich diese große Anzahl an Quadraten am besten einfärben?
Die Methode, die ich bisher verwendet habe, besteht darin, vor dem Zeichnen jedes Quadrats die Farbe fillcolor
mithilfe des Makros zu definieren \definecolor
und das Quadrat mit dieser Farbe zu füllen. Das bedeutet, dass ich jedes Mal, wenn ich ein neues Quadrat zeichne, erneut eine Definition vornehme fillcolor
.
Ich bin mir jedoch nicht so sicher, ob das der richtige Weg ist. pdflatex scheint beim Kompilieren des Dokuments sehr viel Speicher zu benötigen und aus irgendeinem seltsamen Grund geht der Speicher aus, wenn ich mehr als 5 Bilder einfüge (selbst wenn ich die Speichermenge verzehnfache, wenn ich von 5 auf 6 Bilder gehe). Besteht die Möglichkeit, dass es alle Farben speichert, die ich definiert habe und die ich pdflatex „vergessen“ lassen muss, fillcolor
bevor ich es \definecolor
erneut aufrufe?
Aktualisieren:Unten sehen Sie ein Beispiel für eines der TikZ-Bilder, die ich in meinem Dokument haben möchte (es handelt sich um eine Visualisierung des Phasenanteilsfelds in einer Zweiphasenflüssigkeitssimulation unter Verwendung der Finite-Volumen-Methode und der Fluidvolumenmethode, und ja, ich weiß, die Flüssigkeitsschnittstelle ist nicht gerade scharf):
Dieses spezielle Bild besteht aus 1990 ausgefüllten Quadraten und 4 nicht ausgefüllten Quadraten.
Zunächst wird für jedes Quadrat fillcolor
mit definiert \definecolor
und das Quadrat mit dieser Farbe gefüllt:
\definecolor{fillcolor}{rgb}{1.000000,0.241735,0.000000}
\fill[fillcolor] (0.203125,0.578125) rectangle (0.218750,0.593750);
Dann werden die Seiten jedes Quadrats gezeichnet, zum Beispiel
\draw (0.203125,0.578125) rectangle (0.218750,0.593750);
Antwort1
Wie ich in einem Kommentar sagte: Wenn \definecolor
die Farbdefinition einfach in einem TeX-Makro gespeichert wird, wird bei einer Neudefinition dasselbe Makro wiederverwendet und somit nicht mehr Speicher verbraucht.
Es ist jedoch auch möglich, dass \defincolor
eine Art wörtlicher PDF-Code übertragen wird, der die Farbe für die PDF-Engine definiert. In diesem Fall sollte, soweit ich es verstehe, auch kein weiterer Speicher für die mehrmalige Neudefinition derselben Farbe verwendet werden.
Für alle Fälle ist es jedoch möglich, eine RGB-Farbe ohne vorherige Definition zu verwenden. So geht's.
Im Prinzip
tikz
erkennt eine Farbspezifikation der Form{rgb:red,255;green,255;blue:255}
. Sie wird jedoch nicht wie erwartet interpretiert. Beispielsweise[fill={rgb:red,255;green,255;blue,0}]
wird kein Gelb erzeugt, sondern ein schwarz getöntes Gelb (siehe Abbildung unten). Ich konnte keine Dokumentation darüber finden, wie diese Spezifikation funktioniert. Anscheinend werden allered
,green
,blue
Werte addiert und dann jeder einzelne Wert durch die Summe geteilt. Das heißt, was wir angeben, sind keine absoluten Bytewerte, sondern relative Gewichte. Um also Gelb zu erhalten, können wir schreiben:{rgb:red,1;green:1;blue:-1}
. Ich finde diese Syntax ziemlich unpraktisch (außerdem, wie könnten wir „weiß“ erhalten?)PGF verwendet ein internes Makro:
\pgfsys@color@rgb@fill
das das erwartete Verhalten hat. Es empfängt drei numerische Werte für die Komponentenr
,g
undb
als Werte von 0-255. Wir können dieses Makro also verwenden, um die Füllfarbe direkt vor dem Füllbefehl festzulegen.
Hier ist ein Code, der mehrere Optionen zeigt:
\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}
Das Ergebnis:
Antwort2
Ich glaube, dass Ihr Ansatz \definecolor
in Ordnung ist.
Mein Vorschlag wäre, die PGF-Basisebene anstelle von Tikz zu verwenden, d. h. etwas wie
\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
Bitte schlagen Sie die genannten Befehle im pgfmanual.pdf nach, da ich einige davon möglicherweise falsch geschrieben habe (ich habe auswendig zitiert).
Mein Vorschlag, Strich- und Füllpfad zu kombinieren und nur die Farbe zu variieren, könnte für Sie sinnvoll sein und könnte auch auf den Tikz-Pfad angewendet werden. Dies sollte auch den Speicherverbrauch und die Satzzeit reduzieren.
Eine Anmerkung, die eigentlich über den Rahmen Ihrer Frage hinausgeht: Mein Vorschlag, die Zeichenfarbe zu verwenden, fillcolor!80!black
ist von der Standardeinstellung inspiriert, pgfplots
die ich im Vergleich zu schwarzen Umrissen weniger hart finde. Und pgfplots hat den gleichen Anwendungsfall wie hier: Was Sie hier schreiben, ist eigentlich eine Art Netz/Oberfläche mit facettierter Schattierung und expliziter Farbeingabe (in pgfplots:\addplot3[surf]
, vergleichepgfplots: Färben Sie eine (3D-)Oberfläche mit beliebigen RGB-Farben ein.) .
Selbst nach der Speicherreduzierung haben Sie „viele“ Datenpunkte (in Bezug auf das, was TeX verarbeiten soll). Selbst die Reduzierung des Speichers kann also irgendwann an die Grenzen von TeX stoßen. Wenn ein Bild funktioniert, aber mehrere fehlschlagen, kann es von Vorteil sein, Bildexternalisierung zu verwenden. Sie können auch von Vorteil sein, lualatex
anstelle von zu verwenden, pdflatex
da dynamische Speicherzuweisung vorhanden ist. Sie sollten auch mit zwischen benachbarten lualatex
experimentieren\clearpage
figure
Umgebungen mit experimentieren, um sicherzustellen, dass TeX keine alten Zahlen im Speicher hat (wie @JLDiaz in einem Kommentar vorgeschlagen hat). Die Details zur Bildexternalisierung und zum Speicherverbrauch sind im Abschnitt „Speicher- und Geschwindigkeitsüberlegungen“ in zusammengefassthttp://pgfplots.sourceforge.net/pgfplots.pdf
Antwort3
Um eine weiche und einfache Schattierung zwischen Rot und Blau (über Orange, Gelb, Grün und Cyan) zu erzielen, können Sie das Hsb
Farbmodell (im xcolor
Paket bereitgestellt) verwenden:
\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}
Oder (mit anderer Syntax):
\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}
Diese Methode kann bei einer großen Anzahl kleiner Quadrate (hier 100 x 100) angewendet werden:
\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}