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

6
  • 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
    Commented Aug 17, 2016 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
    Commented Aug 17, 2016 at 4:24
  • See section "23.3 Blend Modes" (p. 340, pgfmanual, v3.0.1a). Commented Aug 17, 2016 at 4:51
  • 1
    Use outlined texts (as subtitles) via the contour package to get better results. Commented Aug 17, 2016 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
    Commented Aug 17, 2016 at 9:30

3 Answers 3

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}
4
  • 1
    I find that a white background with opacity is almost always the way to go for such overlaid text
    – Chris H
    Commented Aug 17, 2016 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
    Commented Aug 17, 2016 at 14:48
  • 1
    In my answer, the last example (the scope with the blend group=difference option) blends the text over the image. Commented Aug 17, 2016 at 15:00
  • @PaulGaborit I had forgotten text=white. Very useful answer which gathers most of the possibilities.
    – anderstood
    Commented Aug 17, 2016 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

6
  • 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
    Commented Aug 17, 2016 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
    Commented Aug 17, 2016 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
    Commented Aug 17, 2016 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
    Commented Aug 17, 2016 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
    Commented Aug 17, 2016 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

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .