2

I want to create a custom scale bar for some diagrams in TikZ. I rely heavily on the positioning library to arrange several objects, e.g. the scale bar next to a picture or some labels relative to the scale bar. Now I'd like to use a custom color gradient, for which I created a small PNG and want to fill a rectangle with it. I found a solution how to do than in another TexSE question, but it fails, when the node is positioned relative to another.

What's the problem with my code?

\documentclass{article}

\usepackage{tikz}
    \usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
    \node [
            path picture={
                \node at (path picture bounding box.center) {
                    \includegraphics[height=45mm, width=5mm]{scalebar}};
                },
            draw,rectangle,
            minimum width=5mm, minimum height=45mm,
            ] (ref) {};
    \node [
            path picture={
                \node at (path picture bounding box.center) {
                    \includegraphics[height=45mm, width=5mm]{scalebar}};
                },
            draw,rectangle,
            minimum width=5mm, minimum height=45mm,
            right= of ref
            ] (cal) {};
\end{tikzpicture}

\end{document}

Output: Latex output

Scale bar PNG: scalebar

Edit: I tried Zarko's solution, but with inner sep=0 the boundary becomes to thin to be properly displayed by the PDF viewer unless zoomed in by a large factor. I tested it with the built-in TeXworks viewer and Adobe Reader. The problem is not there if one draws a rectangle with a shading or when using my initial code with path picture. I also tried setting innersep=0.5\pgflinewidth, but the result is the same. Maybe it as something to do with the order in which objects are drawn in the PDF? Is this behavior reproducible for others?

\documentclass{article}

\usepackage{tikz}
    \usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}[
imagebox/.style = {draw,inner sep=0pt,
                   minimum width=5mm, minimum height=45mm}
                    ]
    \node (ref) [imagebox,rectangle,top color=white,bottom color=black] {};
    \node (cal) [imagebox, right= of ref] {\includegraphics[height=45mm, width=5mm]{scalebar}};
\end{tikzpicture}

\end{document}

Output: Latex Output 2

  • Why don't you just define a custom shading and use that? I'm not sure in which sense you want it to be consistent with the greyscale shading, but a custom shading would work in just the same way. On the other hand, maybe your real use case involves a picture rather than a shading? Obviously in that case, a custom shading isn't an option. – cfr Mar 27 '17 at 15:57
  • @cfr I want to add scale bars to images. When I use a standard grey scale LUT, the scale bar can be easily constructed solely with tikz command. On the other hand, when custom LUTs (specific to the image processing software used) are used, I want to use PNGs created with the same image software and the same LUT. I guess an ideal way would be to extract the LUT definition from the imaging software and create the bar in TikZ, but this seems quite tedious. – Cornelius Sicker Mar 27 '17 at 16:24
  • No idea what a LUT is. – cfr Mar 27 '17 at 21:16
  • @cfr LUT means look up table. Think of it as a custom color palette for pictures. – Cornelius Sicker Mar 27 '17 at 21:39
2

See, if this simplified solution works for you:

   \begin{tikzpicture}[
imagebox/.style = {draw,inner sep=\0.5\pgflinewidth,
                   minimum width=5mm, minimum height=45mm}
                    ]
\node (ref) [imagebox]  {\includegraphics[height=45mm, width=5mm] {PhhX6}};%{scalebar}} <-- my copy of your png image has name "PhhX6"
\node (cal) [imagebox, right=of ref]
                        {\includegraphics[height=45mm, width=5mm] {PhhX6}};% {scalebar}};
    \end{tikzpicture}

I tested this with option demo for graphicx, which show that this approach works as desired:

Edit (2. try ):

Off-set of the included image, which you observe in your MWE arise because the node in path picture apparently use wrong anchor. If you define for node in path picture as anchor=center, then your solution will work as desired. With this solution the position macro will work as at all other nodes.

For comparison of both described cases, let serve the following MWE. It contain solutions (from left to right):

  • simplified solution described at the beginning of this answer (on image designated with "C")
  • the case with fill in node (on image designated with "A")
  • your solution with correct defined anchors and new node style, which enable simple use this solution (on image designated with "B").

The MWE:

\documentclass{article}
\usepackage{graphicx}
    \usepackage{tikz}
    \usetikzlibrary{positioning}

\begin{document}
    \begin{tikzpicture}[node distance=2mm]
\tikzset{
    base/.style = {draw, semithick,
        minimum height=45mm, minimum width=5mm,
        inner sep=0pt},
    imagebox/.style = {base,
        path picture={\node[anchor=center]
                            at (path picture bounding box) {#1};},
        node contents={}}
        }
\node (ref) [base,top color=white,bottom color=black!50, pin=A] {};
\node (cal) [imagebox={\includegraphics[height=45mm,width=5mm]{PhhX6}},% copy of your "scalebar" was renamed to "PhhX6"
             right=of ref, pin=B];
\node (xxx) [base,inner sep=0.50\pgflinewidth,left=of ref, pin=C]
                      {\includegraphics[height=45mm,width=5mm,clip]{PhhX6}};
\end{tikzpicture}

\end{document}

which gives:

A comparison of all three cases shows:

  • border lines in all cases are equal. This can be seen if enough increase image (I thing that the impression that image "C" has thinner border line is caused by viewer artifacts, but I may be wrong), see image below (it is taken from recent Acrobat Reader DC):

- image "C" is for thickness of borde

  • image "C" is for thickness of border lines bigger (expected)
  • the benefits of the first proposed solution is simplicity, however, with new defined node style imagebox, which preserve correct positioning of node as well as image included as path image, the use of the second solution is almost the same handy
  • I tried something like this before, but had problems with the rectangular outline not being proberly displayed in the PDF. I edited my question with some code to illustrate. – Cornelius Sicker Mar 23 '17 at 15:27
  • See, if new example is more close to your wish. You can experimenting with other border line width. Image is taken from Sumatra viewer. – Zarko Mar 23 '17 at 15:50
  • It comes close but still the outline vanishes at some zoom levels. Additionaly, I'd like to have a consistent look with the grey level scale bar I generated with top color and bottom color (see edited question). I found a solution which looks good for me. I posted it as a separate answer. I'm not sure if I should accept my own answer, but it works best for me, so far. – Cornelius Sicker Mar 23 '17 at 16:26
  • Thanks for the update. Your comparison shows that the first two bars look consistent and the third bar's left edge looks to thin. So I'll accept my own answer for now. Though, ideally someone could explain the odd behavior of path picture in combination with right=of. Thanks, Zarko, for the continuous struggle towards a better solution! – Cornelius Sicker Mar 24 '17 at 9:30
  • @CorneliusSicker, meanwhile I reinspected my answer, your solution and also claim, that the node's borders thickness are different (around that we disagree :-) ). Anyway, beside first solution I also add solution for your problem, which work correctly in any circumstances and for it define new node style. – Zarko Mar 25 '17 at 12:52
0

By trial and error I found out that the anchor of the node needs to be center for path picture to work properly. Since right=of sets anchor=west things get messed up. A working solution is thus to add anchor=center and adjust the distance accordingly, e.g. by half of the object's width.

\documentclass{article}

\usepackage{tikz}
    \usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
    \node (ref) [draw,rectangle,inner sep=0,minimum width=5mm,minimum height=45mm,top color=white,bottom color=black] {};
    \node [
            path picture={
                \node at (path picture bounding box.center) {
                    \includegraphics[height=45mm, width=5mm]{scalebar}};
                },
            draw,rectangle,
            minimum width=5mm, minimum height=45mm,
            right=of ref,
            anchor=center
          ] (cal) {};
\end{tikzpicture}

\end{document}

Output (Adobe Reader): Latex output

  • you can accept own answer, but before see my last edit of my answer, in which I add comparison of yours and mine solution. Up to you is, which one you will use or accept. – Zarko Mar 23 '17 at 22:27
  • @Zarko Thanks for the update. I left a comment there. – Cornelius Sicker Mar 24 '17 at 9:28
  • @Zarko Would you care to elaborate how I misinterpreted your solution or/and how my solution is not correct? I suggest to revive your answer if that's possible since it had some upvotes (also from me) and provides an alternative which might be valuable to someone else. I'd also like to understand what I might have seen or understood wrong. – Cornelius Sicker Mar 24 '17 at 12:36

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.