TransWikia.com

Representing a special TikZ node on a 1D, logarithmic axis with meaningful units

TeX - LaTeX Asked on June 3, 2021

This question is aimed at building on the great solution provided here. NB the link to the plot which serves as a great example of what we are building.

For simplicity’s sake, consider the following example:

documentclass[tikz]{standalone}
usetikzlibrary{calc,fadings}
usepackage{miscchemsym}

defsolutelength{1}
defsoluteheight{.5}
defsolutevariabilityhigh{0}
defsolutevariabilitylow{0}
defsolutelabelcolor{black}
tikzset{
    pics/solute/.default={s-s},
    pics/solute/.style args={#1-#2}{
        code={
            defhasfading{f}
            defstylehigh{#2}
            defstylelow{#1}
            coordinate (-north) at ({.5*solutelength},soluteheight);
            coordinate (-south) at ({.5*solutelength},0);
            coordinate (-south west) at (0,0);
            coordinate (-south east) at (solutelength,0);
            coordinate (-north west) at (0,soluteheight);
            coordinate (-north east) at (solutelength,soluteheight);
            coordinate (-south west reduced) at ({0+solutevariabilitylow},0);
            coordinate (-south east reduced) at ({solutelength-solutevariabilityhigh},0);
            coordinate (-north west reduced) at ({0+solutevariabilitylow},soluteheight);
            coordinate (-north east reduced) at ({solutelength-solutevariabilityhigh},soluteheight);
            ifxstylelowhasfading
                fill (-south west reduced) -- (-south) -- (-north) -- (-north west reduced) -- cycle;
                fill[left color=.!0, right color=.] (-south west) -- (-south west reduced) -- (-north west reduced) -- (-north west) -- cycle;
            else
                fill (-south west reduced) -- (-south) -- (-north) -- (-north west) -- cycle;
            fi
            ifxstylehighhasfading
                fill (-south) -- (-south east reduced) -- (-north east reduced) -- (-north) -- cycle;
                fill[left color=., right color=.!0] (-south east reduced) -- (-south east) -- (-north east) -- (-north east reduced) -- cycle;
            else
                fill (-south) -- (-south east reduced) -- (-north east) -- (-north) -- cycle;
            fi
            node[text=solutelabelcolor] (-label) at ($(-south west) !0.5! (-north east)$) {tikzpictextstrut};
        },
    },
    solute/length/.code={
        defsolutelength{#1}
    },
    solute/height/.code={
        defsoluteheight{#1}
    },
    solute/variability high/.code={
        defsolutevariabilityhigh{#1}
    },
    solute/variability low/.code={
        defsolutevariabilitylow{#1}
    },
    solute/label color/.code={
        defsolutelabelcolor{#1}
    },
    solute/label/.style={
        pic text={#1}
    },
}

% the interface

% 1 - low concentration
% 2 - somewhat arbitrary, vertical positioning, user has to manage these manually
% 3 - color
% 4 - length (equal to abs max concentration - absolute min concentration)


begin{document}

    begin{tikzpicture}
        draw[-stealth, thick] (0,0) -- (11,0);
        foreach x in {0,...,10} {
            draw (x,.1) -- ++(0,-.2);
        }
        
        draw (0,.2) pic[yellow, solute/length=6, solute/label={a}] {solute};
        
        draw (1,-.7) pic[cyan, solute/length=5, solute/label={b}] {solute};        

    end{tikzpicture}

end{document}

The x-axis will span from 1 nM to 100 mM (8 or so orders of magnitude). The following tickmarks will be present and will have labels represented 1 nM (1e-9 of the common unit of M), 1 {mu}M (1e-6 of the common unit of M), 1 mM (1e-3 of the common unit of M), and 100 mM (1e-1 of the common unit of M). Other tickmarks can be drawn – can be decided based on defaults and aesthetics.

The user will provide values corresponding to either nM or M, whichever is most numerically convenient for the compiler.

The question is, how best to adapt the MWE to include the following:

begin{axis}[
    xmode=log,
    xmin=1e-9, xmax=1e-1,
    axis x line=bottom,% only show the bottom x axis
    hide y axis,    
    ymin=0,ymax=5]

% calls to various nodes placed here.

end{axis}

as well as, handling values as arguments to which explicit and meaningful engineering units are associated.

One Answer

Here is a solution. I didn't use the approach linked from the other question because I felt it was overcomplicating things. It's important to use pgfplotsset{compat=newest}, since this allows the coordinates within solute to use the coordinate system of the axis.

I don't think real-world units should be supported, as this adds a lot of complexity and it's reasonable enough for the user to convert to decimals, etc. You can also explore more about axis to style it with labels etc. as needed.

There can be tiny line artifacts where the separate shapes meet, but this is a known issue that's basically a rendering rounding bug. Also, the ymin/ymax arguments are ignored, but it breaks if you leave them out. Not sure what's going on there...

EDIT: added x axis label.

MWE

documentclass[margin=5mm]{standalone}
usepackage{pgfplots}
pgfplotsset{compat=newest}
usetikzlibrary{calc,fadings}
usepackage{xifthen}
newlength{dx}setlength{dx}{10mm}
newlength{dy}setlength{dy}{5mm}
newlength{hy}setlength{hy}{0.5dy}
newcommand{solute}[9]{% args:
  % 1: name, 2: color, 3: y-height,
  % 4: left (f)ade or (w)edge, 5: leftmost-x,  6: end left fade/wedge,
  % 7: start right fade/wedge, 8: rightmost-x, 9: right (f)ade or (w)edge
  fill[fill=#2] (#6,#3dy-hy) rectangle (#7,#3dy+hy) node[pos=.5] {#1};
  ifthenelse{equal{#4}{f}}
    {fill[#2,path fading=west] (#5,#3dy-hy) rectangle (#6,#3dy+hy);}
    {fill[#2] (#5,#3dy+hy) -- (#6,#3dy+hy) -- (#6,#3dy-hy) -- cycle;}
  ifthenelse{equal{#9}{f}}
    {fill[#2,path fading=east] (#7,#3dy-hy) rectangle (#8,#3dy+hy);}
    {fill[#2] (#8,#3dy+hy) -- (#7,#3dy+hy) -- (#7,#3dy-hy) -- cycle;}
}
begin{document}
  begin{tikzpicture}
    begin{axis}[axis lines = middle,
      ymin=0, ymax=0, hide y axis,
      xmin=1, xmax=1e4, xmode = log]
    solute{A}{green} { 2}{f}{10}{100}{1500}{4000}{w}
    solute{B}{yellow}{ 1}{w}{ 1}{ 20}{ 300}{ 500}{f}
    node[anchor=north] at (1e2,-dy){Concentration [mM]};
    end{axis}
  end{tikzpicture}
end{document}

Result

result

Correct answer by jessexknight on June 3, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP