15

There is probably no simple and general solution to this, but is it possible in tikz to write text in the negative color of the background, whatever the background?

To illustrative the problem (but I am not asking for a solution specific to this background):

\documentclass[tikz]{standalone}

\begin{document}
\begin{tikzpicture}
\shade[left color=black,right color=red] (0,0) rectangle (4,2);
\node at (2,1) {this text is hard to read};
\end{tikzpicture}
\end{document}

enter image description here

Negative is to be understood in any sense (complementary color, complementary to black), it does not really matter. The idea is to get something readable for any background.

Edit This is a comparison of the different methods suggested.

  • First column: original (black text), 400 is not easy to read
  • Second column: what I requested: not a good idea at all!
  • Third column: white text with black contour: hardly readable when small
  • Fourth column: black text on white background with opacity: my favorite
  • Fifth column: white text in black background: I like it too, but slightly prefer the fourth one here because it's lighter.

enter image description here

  • 1
    Doesn't white do well in most instances? (And black in the remaining ones?) I'm not convinced that what you're asking for would look good or be necessarily legible. – JPi Aug 17 '16 at 3:26
  • @JPi White is generally worse, and the thing is this is generated by two loops, so it's cumbersome to manually change the color. But I agree that there are workarounds. – anderstood Aug 17 '16 at 4:24
  • See section "23.3 Blend Modes" (p. 340, pgfmanual, v3.0.1a). – Paul Gaborit Aug 17 '16 at 4:51
  • 1
    Use outlined texts (as subtitles) via the contour package to get better results. – Paul Gaborit Aug 17 '16 at 4:55
  • 2
    While a manual choice of white or black often works, it's not always optimal, so this might be useful. But consider that the negative of mid grey (#808080) is itself and you'll see where an overreliance on this automation would let you down. – Chris H Aug 17 '16 at 9:30
21

The short answer is: use blend modes (p.340, pgfmanual v3.0.1a) with difference mode.

But, for better results, you may use outlined text or background with opacity. The following picture shows different tests:

enter image description here

\documentclass[tikz]{standalone}
\usepackage[outline]{contour}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
  \node (a) {\includegraphics{tiger}};

  \path (a.north) -- (a.south)
  \foreach \pos in {1,...,7}{coordinate[pos=\pos/8] (p-\pos)};

  \tikzset{my text/.style={text=white,font=\Huge\bfseries}}
  \def\mytext{Test of long text}

  \node[my text] (ex) at (p-1) {\mytext};
  \node[anchor=east] at (ex -| a.west) {white text};

  \node[my text,text=black](ex) at (p-2) {\mytext};
  \node[anchor=east] at (ex -| a.west) {black text};

  \node[my text,fill opacity=.5,fill=black,text opacity=1] (ex) at (p-3) {\mytext};
  \node[anchor=east] at (ex -| a.west) {black background with opacity};

  \node[my text,text=black,fill opacity=.5,fill=white,text opacity=1] (ex) at (p-4) {\mytext};
  \node[anchor=east] at (ex -| a.west) {white background with opacity};

  \node[my text] (ex) at (p-5) {\contour{white}{\mytext}};
  \node[anchor=east] at (ex -| a.west) {white outlined text};

  \node[my text] (ex) at (p-6) {\contour{black}{\textcolor{white}{\mytext}}};
  \node[anchor=east] at (ex -| a.west) {black outlined text};

  \begin{scope}[blend group=difference]
    \clip ($(p-7 -| a.west) + (0,1.1em)$) rectangle ($(p-7 -| a.east) + (0,-1.1em)$);
    \node {\includegraphics{tiger}};
    \node[my text] (ex) at (p-7) {\mytext};
  \end{scope}
  \node[anchor=east] at (ex -| a.west) {\emph{required} blended text (difference)};
\end{tikzpicture}
\end{document}
  • 1
    I find that a white background with opacity is almost always the way to go for such overlaid text – Chris H Aug 17 '16 at 9:31
  • I am building a comparison of the different suggested methods; however, I cannot get the blend mode work with text, instead of fill or graphics. I did not find examples except with fading and patterns. Can this be done simply? – anderstood Aug 17 '16 at 14:48
  • 1
    In my answer, the last example (the scope with the blend group=difference option) blends the text over the image. – Paul Gaborit Aug 17 '16 at 15:00
  • @PaulGaborit I had forgotten text=white. Very useful answer which gathers most of the possibilities. – anderstood Aug 17 '16 at 15:54
8

A nonanswer : You are making a bad decision worse. First you don't need t= prefix because they are all t values. If you remove that you have the option to put a corner box with solid background with designated four character long width and one character long height

\documentclass[tikz]{standalone}
\usepackage{mwe} % <- for dummy images
\begin{document}
\begin{tikzpicture}[
cornerbox/.style 2 args={
  path picture={
    \node{\includegraphics[width=1cm,height=1cm]{#1}};
    \node[fill=black,text=white,
          minimum width=3ex,minimum height=1ex,
          anchor=north west,
          outer sep=0,font=\sffamily\tiny] 
          at (path picture bounding box.north west) {#2};
  },
  inner sep=0,
  minimum size=1cm
}
]

\node[cornerbox={example-image}{$\infty$},draw,thick] at (0,0) {};
\node[cornerbox={example-image-a}{200},draw,thick] at (1,0) {};
\node[cornerbox={example-image-b}{5000},draw,thick] at (2,0) {};
\end{tikzpicture}
\end{document}

Here you can make the annotation box as small as you wish, such that visually impaired and colorblinds can actually read your data.

enter image description here

  • You'd often be better showing the units than the symbol for the value being measured, but this wouldn't save much space. If t is time though, I can't wait for the paper to come out given the ∞. – Chris H Aug 17 '16 at 9:33
  • 1
    @ChrisH I agree but for grouped graphics, it is not a good idea to be pedantic about the conventions. It is the message that counts not correctness. – percusse Aug 17 '16 at 11:55
  • Yes, I think I'd put "t=10 s" in the first and 20, 30 or whatever in the subsequent boxes, so that the figure made sense on its own but with the fewest characters. Or something like that – Chris H Aug 17 '16 at 13:17
  • 1
    @ChrisH "t" is dimensionless, and I see no problem with t=\infty meaning the limit when t\to \infty, given that such a limit exists. Percusse's suggestion is nice, but a bit too invasive for the present purpose (I'll add a comparison when I managed to blend text and image). – anderstood Aug 17 '16 at 14:50
  • 1
    @ChrisH Here t is dimensionless time; the images are not from experiments but from numerical simulations. The thumbnails with t=\infty mean that there is no significant change between t=1000, t=10000, t=100000, etc. or in other word, that the numerical solution has converged to a stationnary solution. I agree that t=\infty would be strange in experimental work! – anderstood Aug 17 '16 at 15:08
5

Intriguing question, to which I don't know the answer. However, you can mimic this effect doing something like this:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{fadings}
\usepackage{lipsum}
\newcommand\fadingtext[3][]{%
    \begin{tikzfadingfrompicture}[name=fading letter]
        \node[text=transparent!0,inner xsep=0pt,outer xsep=0pt,#1] {#3};
    \end{tikzfadingfrompicture}%
    \begin{tikzpicture}[baseline=(textnode.base)]
    \node[inner sep=0pt,outer sep=0pt,#1](textnode){\phantom{#3}}; 
    \shade[path fading=fading letter,#2,fit fading=false]
    (textnode.south west) rectangle (textnode.north east);% 
    \end{tikzpicture}% 
}

\begin{document}
\begin{tikzpicture}
\shade[left color=black,right color=red] (0,0) rectangle (4,2) (2,1) node{\fadingtext{left color=white, right color=yellow}{this text is easier to read}};
\end{tikzpicture}


\end{document}

(example based on another answer on this forum)

enter image description here

  • Yes, but I specifically asked for a general solution (i.e. without specifying the text colors) :) – anderstood Aug 17 '16 at 3:13
  • 5
    Which is why I said that I didn't know the answer... – JPi Aug 17 '16 at 3:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.