2

I have a TikZ figure, where one axis is a bit overpopulated. My solution is to add further lines to the labels using

extra x ticks={...},
extra x tick label={...},
extra x style={tick label style={yshift=...}},

However, I can only add a second line with this method. I know an option is simply to add a node with some text in the desired position, but I would like to know if there is a solution using the axis options. My code which does not work:

\documentclass[10pt,a4paper]{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{intersections}
\pgfplotsset{compat=1.14}
\begin{document}

\begin{tikzpicture}
% Define parameters
\newcommand*{\DELTAb}{0.25}%
\newcommand*{\DELTAa}{0.4}%     
\pgfmathsetmacro{\LOWB}{1-\DELTAb}%
\pgfmathsetmacro{\HIGHB}{1+\DELTAb}%
\pgfmathsetmacro{\LOWA}{1-\DELTAa}%
\pgfmathsetmacro{\HIGHA}{1+\DELTAa}%    
\newcommand*{\ALPHA}{0.5}%      
\begin{axis}[
% Define axis properties
axis x line=bottom,
axis y line=left,
enlargelimits=false, 
clip=false,
ytick=\empty,%{1},
ymin=0,
%ymax=1,
xtick={0, \LOWB, 1, \HIGHB},
xticklabels={$0$, $w-\Delta_b$, $w$, $w+\Delta_b$},
extra x ticks={0.9},
extra x tick labels={$w - \Delta_b(\delta_{b,2} - \delta_{b,1})$},
extra x tick style={tick label style={yshift=-4mm}},
extra x ticks={\LOWA, \HIGHA},
extra x tick labels={$w-\delta_b$, $w+\delta_b$},
extra x tick style={tick label style={yshift=-8mm}},    
xmin=0.43,
xmax=1.8,
samples=250,
domain=0.55:1.6]
% Draw functions
\addplot[name path=A,smooth,thick,mark=none] {(1/x)^(1/(1-\ALPHA))} node[right,pos=1,yshift=-0.1cm] {$f(w_i)=C{w_i}^{\frac{-\rho}{1-\rho}}$};
% Find intersections    
\path[name path=C] (\pgfkeysvalueof{/pgfplots/xmin},0) -- (\pgfkeysvalueof{/pgfplots/xmax},0); % X axis named
\path[name path=D] (0,\pgfkeysvalueof{/pgfplots/ymin}) -- (0,\pgfkeysvalueof{/pgfplots/ymax}); % Y axis named
\path[name path=vline0] (1,0) -- (1,5); %vertical line1 in w
\path[name path=vline1] (\LOWB,0) -- (\LOWB,5); %vertical line in -delta
\path[name path=vline2] (\HIGHB,0) -- (\HIGHB,5); %vertical line in +delta
\path[name path=vline3] (\LOWA,0) -- (\LOWA,5); %vertical line in -delta
\path[name path=vline4] (\HIGHA,0) -- (\HIGHA,5); %vertical line in +delta  
\path[name intersections={of=vline0 and A,name=v0A}]; % Create intersection at average
\path[name intersections={of=vline1 and A,name=v1A}]; % Create intersection-1
\path[name intersections={of=vline2 and A,name=v2A}]; % Create intersection-3
\path[name intersections={of=vline3 and A,name=v1B}]; % Create intersection-1
\path[name intersections={of=vline4 and A,name=v2B}]; % Create intersection-3   
% Draw lines                                        
\draw[dashed,thick,gray] (v1B-1) -- (\LOWA,0);
\draw[dashed,thick,gray] (v2B-1) -- (\HIGHA,0); 
\draw[dashed,thick,gray] (v1A-1) -- (\LOWB,0);
\draw[dashed,thick,gray] (v2A-1) -- (\HIGHB,0);     
\draw[dashed,thick,gray] (1, 0) -- (v0A-1); 
% Draw averages
\path[draw,solid,red,name path=P1] (v2A-1) -- (v1A-1);
\path[name path=vline0b] (0.9,0) -- (0.9,5); %vertical line1 in w   
\path[name intersections={of=vline0b and P1,name=v0Ab}]; % Create intersection below average    
\draw[dashed,gray] (v0Ab-1-|{axis cs:0.43,0}) -- (v0Ab-1) node[left,black,pos=0] {$\lambda^{HET}_a$};
\draw[dashed,gray] (0.9,0) -- (v0Ab-1); 
\path[draw,solid,red,name path=P2] (v2B-1) -- (v1B-1);  
\end{axis}
\end{tikzpicture}   

\end{document}

The result:

enter image description here

So basically, you cannot have two set of extra x ... commands, as the last one overrides any previous one.

2
  • is rotating xtick labels and than have it in line an option? – Zarko Aug 7 '17 at 16:04
  • @Zarko That is an option (which hasn't occur to me, thanks), and I know how to do that, but still I want to know how to add a third line. I have rather long entries and would like to try this mode. – luchonacho Aug 7 '17 at 16:06
2

You can have one set of extra labels, and have different shifts, as in Individual tick label style depending on position:

extra x ticks={0.9,\LOWA, \HIGHA},
extra x tick labels={{$w - \Delta_b(\delta_{b,2} - \delta_{b,1})$},$w-\delta_b$, $w+\delta_b$},
extra x tick style={tick label style={yshift={\ticknum == 0 ? "-4mm" : "-8mm"}}},

The <comparison> ? <value1> : <value2> is a shorthand for ifthenelse, you could also use the more obvious ifthenelse(\ticknum==0,"-4mm","-8mm").

In the code below I also suggest a somewhat less verbose method for making that diagram, by defining a function and using a ycomb plot instead of calculating all those intersections.

output of below code

\documentclass[10pt,a4paper]{article}
\usepackage{pgfplots}
\usetikzlibrary{intersections}
\pgfplotsset{compat=1.14}
\begin{document}

\begin{tikzpicture}
% Define parameters
\newcommand*{\DELTAb}{0.25}%
\newcommand*{\DELTAa}{0.4}%     
\pgfmathsetmacro{\LOWB}{1-\DELTAb}%
\pgfmathsetmacro{\HIGHB}{1+\DELTAb}%
\pgfmathsetmacro{\LOWA}{1-\DELTAa}%
\pgfmathsetmacro{\HIGHA}{1+\DELTAa}%    
\newcommand*{\ALPHA}{0.5}%      

\begin{axis}[
% Define axis properties
axis x line=bottom,
axis y line=left,
enlargelimits=false, 
clip=false,
ytick=\empty,
ymin=0,
xtick={0, \LOWB, 1, \HIGHB},
xticklabels={$0$, $w-\Delta_b$, $w$, $w+\Delta_b$},
extra x ticks={0.9,\LOWA, \HIGHA},
extra x tick labels={{$w - \Delta_b(\delta_{b,2} - \delta_{b,1})$},$w-\delta_b$, $w+\delta_b$},
extra x tick style={tick label style={yshift={ifthenelse(\ticknum==0,"-4mm","-8mm")}}},
xmin=0.43,
xmax=1.8,
samples=50,
domain=0.55:1.6,
declare function={f(\x)=(1/\x)^(1/(1-\ALPHA));}
]


% Draw functions
\addplot[name path=A,smooth,thick,mark=none] {f(x)}
node[right,yshift=-0.1cm] {$f(w_i)=C{w_i}^{\frac{-\rho}{1-\rho}}$};

\addplot [ycomb,mark=none,dashed,thick,gray,samples at={1,\LOWB,\HIGHB,\LOWA,\HIGHA}] {f(x)};

\draw [red] (\LOWA,{f(\LOWA)}) -- (\HIGHA,{f(\HIGHA)});
\draw [red,name path=A] (\LOWB,{f(\LOWB)}) -- (\HIGHB,{f(\HIGHB)});

\path [name path=B] (0.9,\pgfkeysvalueof{/pgfplots/ymin}) -- (0.9,\pgfkeysvalueof{/pgfplots/ymax});
%
\draw [
  name intersections={of=A and B,name=I},
  thick,dashed,gray
] 
  (0.9,\pgfkeysvalueof{/pgfplots/ymin}) -- (I-1) -- (\pgfkeysvalueof{/pgfplots/xmin},0 |- I-1) node[left,black] {$\lambda^{HET}_a$};

\end{axis}
\end{tikzpicture}   

\end{document}
2
  • Oh, nice how logical expressions embed into the commands! Regarding your simplifying suggestion, looks nice too, although it uses pgfplots rather than tikz, which I am less familiar with (reason why I did not add the pgfplots tag in the first place). It definitively looks neater though! – luchonacho Aug 7 '17 at 16:36
  • @luchonacho Your question is about manipulating axis labels for a pgfplots plot, which, while it might involve TikZ commands, should warrant a pgfplots tag, even if you're less familiar with it. – Torbjørn T. Aug 7 '17 at 16:42

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.