Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This question is a follow up to this question, that allowed me to solve the two dimensional case.

For example this plot

sine

is created by the following code:

\documentclass{minimal}
\usepackage{tikz}
\usepackage{pgfplots}
\def\axisdefaultwidth{360pt}
\pgfkeys{/pgfplots/x axis shift down/.style={
  x axis line style={yshift=-#1},
  xtick style={yshift=-#1},
  xticklabel shift={#1}}}
\pgfkeys{/pgfplots/y axis shift left/.style={
  y axis line style={xshift=-#1},
  ytick style={xshift=-#1},
  yticklabel shift={#1}}}

\pgfplotsset{
  every axis/.append style={thick},tick style={thick,black},
  range frame/.style={
    tick align=outside,
    scaled ticks=false,
    axis lines*=left,
    enlargelimits=false,
    x axis shift down=10pt,
    y axis shift left=10pt,
    line cap=round,
    clip=false,
    after end axis/.code={
       \draw (xticklabel* cs:0,10pt) -- ++(0,-\pgfkeysvalueof{/pgfplots/major tick length});
       \draw (xticklabel* cs:1,10pt) -- ++(0,-\pgfkeysvalueof{/pgfplots/major tick length});
       \draw (yticklabel* cs:0,10pt) -- ++(-\pgfkeysvalueof{/pgfplots/major tick length},0);
       \draw (yticklabel* cs:1,10pt) -- ++(-\pgfkeysvalueof{/pgfplots/major tick length},0);
    }
}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[range frame,xtick={0,90,180,270,360}]
    \addplot[domain=0:360,samples=201] {sin(x)};
  \end{axis}
\end{tikzpicture}
\end{document}

Similarly

pdf

is created by:

\documentclass{minimal}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\def\axisdefaultwidth{360pt}
\pgfkeys{/pgfplots/x axis shift down/.style={
  x axis line style={yshift=-#1},
  xtick style={yshift=-#1},
  xticklabel shift={#1}}}
\pgfkeys{/pgfplots/y axis shift left/.style={
  y axis line style={xshift=-#1},
  ytick style={xshift=-#1},
  yticklabel shift={#1}}}

\pgfplotsset{
  every axis/.append style={thick},tick style={thick,black},
  range frame/.style={
    tick align=outside,
    scaled ticks=false,
    axis lines*=left,
    enlargelimits=false,
    x axis shift down=10pt,
    y axis shift left=10pt,
    line cap=round,
    clip=false,
    after end axis/.code={
       \draw (xticklabel* cs:0,10pt) -- ++(0,-\pgfkeysvalueof{/pgfplots/major tick length});
       \draw (xticklabel* cs:1,10pt) -- ++(0,-\pgfkeysvalueof{/pgfplots/major tick length});
       \draw (yticklabel* cs:0,10pt) -- ++(-\pgfkeysvalueof{/pgfplots/major tick length},0);
       \draw (yticklabel* cs:1,10pt) -- ++(-\pgfkeysvalueof{/pgfplots/major tick length},0);
    }
  }
}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[range frame,ytick={0},extra y ticks={0.398942},extra y tick labels={$\frac{1}{\sqrt{2π}}$},xtick=\empty,extra x ticks={-3,-2,-1,1,2,3},extra x tick labels={$-3σ$,$-2σ$,$-σ$,$σ$,$2σ$,$3σ$}]
    \addplot[domain=-5:5,samples=201,name path=A] {exp(-x^2/2)/sqrt(2*pi)};
    \path[name path=B] (axis cs:\pgfkeysvalueof{/pgfplots/xmin},0) -- (axis cs:\pgfkeysvalueof{/pgfplots/xmax},0);
    \addplot[black!30] fill between[of=A and B,soft clip={(axis cs:-3,0) rectangle (axis cs:3,1)}];
    \addplot[black!20] fill between[of=A and B,soft clip={(axis cs:-2,0) rectangle (axis cs:2,1)}];
    \addplot[black!10] fill between[of=A and B,soft clip={(axis cs:-1,0) rectangle (axis cs:1,1)}];
  \end{axis}
\end{tikzpicture}
\end{document}

Now I would like to achieve the same range frame axis style in a three dimensional plot. My best attempt is:

\documentclass{minimal}
\usepackage{tikz}
\usepackage{pgfplots}
\def\axisdefaultwidth{360pt}
\pgfplotsset{
  every axis/.append style={thick},tick style={thick,black},
  range3frame/.style={
    tick align=outside,
    scaled ticks=false,
    enlargelimits=false,
    ticklabel shift={10pt},
    axis lines*=left,
    line cap=round,
    clip=false
  }
}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[view={55}{45}]
    \addplot3[mesh,samples=41,domain=0:360] {sin(x)*sin(y)};
  \end{axis}
\end{tikzpicture}
\begin{tikzpicture}
  \begin{axis}[range3frame,view={55}{45}]
    \addplot3[mesh,samples=41,domain=0:360] {sin(x)*sin(y)};
  \end{axis}
\end{tikzpicture}
\end{document}

which yields

sineXtimessineY

The option ticklabel shift={10pt}, does exactly the right thing for the tick mark labels. p. 286 of the pgfplots manual states:

Shifts tick labels in direction of the outer unit normal of the axis by an amount of ...

Compare the two versions of the sin(x)sin(y)-plot above, the tick mark labels in the lower plot moved away from the axis just right.

Unfortunately there is no tickmark shift option to shift the tick marks along the outer unit normal vector in the same way. And also no axis shift option to offset the axis.

In the two dimensional solution the trick was to use xshift and yshift transformation in the x axis line style to simply shift the axis and in the xtick style to shift the tick marks.

Is there a way to access the outer unit normal vector from the tickmark shift option and use a transformation to move the axis and the tickmarks in the same way as the tickmark labels?

share|improve this question

1 Answer 1

up vote 6 down vote accepted

There is no such predefined style.

But here is one defined in 5 lines:

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\def\axisdefaultwidth{360pt}

\pgfplotsset{
  every axis/.append style={thick},tick style={thick,black},
  %
  % #1 = x, y, or z
  % #2 = the shift value
  /tikz/normal shift/.code 2 args={%
    \pgftransformshift{%
        \pgfpointscale{#2}{\pgfplotspointouternormalvectorofticklabelaxis{#1}}%
    }%
  },%
  %
  range3frame/.style={
    tick align=outside,
    scaled ticks=false,
    enlargelimits=false,
    ticklabel shift={10pt},
    axis lines*=left,
    line cap=round,
    clip=false,
    xtick style={normal shift={x}{10pt}},
    ytick style={normal shift={y}{10pt}},
    ztick style={normal shift={z}{10pt}},
    x axis line style={normal shift={x}{10pt}},
    y axis line style={normal shift={y}{10pt}},
    z axis line style={normal shift={z}{10pt}},
  }
}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[range3frame,view={55}{45}]
    \addplot3[mesh,samples=41,domain=0:360] {sin(x)*sin(y)};
  \end{axis}
\end{tikzpicture}
\end{document}

The command \pgfplotspointouternormalvectorofticklabelaxis{x} is a shortcut for \pgfplotspointouternormalvectorofaxis{\pgfplotsticklabelaxisspec{x}}. I fear the documentation for \pgfplotspointouternormalvectorofticklabelaxis is missing in the reference manual.

Note that this shift is incompatible with the grid lines (by construction!). To see this, try to add grid=major and you will see the the descriptions are slightly off. You may need to decide if that is what you want (or how to repair it).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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