2

For quite some time, I have been searching for a way to insert axis tick labels of plots within the frame/area of the plot. I think it less disturbs the axis labels themselves. However, there is an issue at the origin where the x tick and y tick labels overlap. One way is to place the tick labels differently as follows:

enter image description here

It is slightly repetitive but at least all the information is there. I am wondering whether there is a way to "automatically" achieve this with pgfplots?

The tikz code is provided below:

\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{libertine}
\usepackage[libertine]{newtxmath}   % Math fonts

\usepackage{filecontents}
\begin{filecontents*}{testt.txt}
-1 -1
1 2
2 4
3 2
4 1
5 0
\end{filecontents*}

\begin{filecontents*}{testp.txt}
-1 6
1 4
2 2
3 1.5
4 2
5 3
\end{filecontents*}

\begin{document}
\begin{tikzpicture}[scale=2]
\fill[gray!10] (1,1) rectangle (4,4);
\node[rotate=90,above,font=\small] at (1,2.5) {intensity};
\node[below,font=\small] at (2.5,1) {size};
\begin{scope}
\clip (1,1) rectangle (4,4);
% grid
\foreach \i in {1,2,...,4} 
    {
    \draw[gray!50] (\i,1) -- (\i,4);
    \draw[gray!50] (1,\i) -- (4,\i);
    }
% axis labels
\foreach \i in {2,3} 
    {
    \node[gray!50,above,fill=gray!10,font=\tiny,inner sep=2pt,yshift=2pt] at (\i,1) {\i};
    \node[gray!50,below,fill=gray!10,font=\tiny,inner sep=2pt,yshift=-2pt] at (\i,4) {\i};
    \node[gray!50,below,fill=gray!10,font=\tiny,inner sep=2pt,xshift=2pt,rotate=90] at (1,\i) {\i};
    \node[gray!50,above,fill=gray!10,font=\tiny,inner sep=2pt,xshift=-2pt,rotate=90] at (4,\i) {\i};
    }
% corner labels
\node[gray!50,above left,fill=gray!10,font=\tiny,inner sep=2pt,xshift=-2pt,rotate=90] at (4,4) {4};
\node[gray!50,below right,fill=gray!10,font=\tiny,inner sep=2pt,yshift=-2pt] at (1,4) {1};
\node[gray!50,above left,fill=gray!10,font=\tiny,inner sep=2pt,yshift=2pt] at (4,1) {4};
\node[gray!50,below right,fill=gray!10,font=\tiny,inner sep=2pt,xshift=2pt,rotate=90] at (1,1) {1};
\draw[line width=1pt] plot[smooth] file {testt.txt};
\draw[line width=1pt,red] plot[smooth] file {testp.txt};
\end{scope}
\draw[color=gray] (1,1) rectangle (4,4);
\end{tikzpicture}
\end{document}

1 Answer 1

2

Here is a proposal. It has a lot of stuff in the definitions but generating the plot is then as simple as

 \begin{tikzpicture}[pluton={width=8cm,height=8cm,xmin=1,xmax=4,xtick={2,3},ymin=0.9,ymax=4.1,ytick={2,3}}]
\begin{axis}[pluton first axis,xlabel=size,ylabel=intensity]
 \addplot[line width=1pt,smooth] table {testt.txt};
 \addplot[line width=1pt,color=red,smooth] table {testp.txt};
\end{axis}
\end{tikzpicture}

The reason why you need to pass all these options to the ambient tikzpicture is that we need to draw two axes in order to have the labels on all sides. So we want to have these values inside the tikzpicture group in two axes, where the second axis, whose whole purpose is to add the labels, gets executed automatically.

Full code including yours:

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{filecontents}
\begin{filecontents*}{testt.txt}
-1 -1
1 2
2 4
3 2
4 1
5 0
\end{filecontents*}

\begin{filecontents*}{testp.txt}
-1 6
1 4
2 2
3 1.5
4 2
5 3
\end{filecontents*}
\usepackage{pgfplots} 
\pgfplotsset{compat=1.16} 
\begin{document}
\begin{tikzpicture}[scale=2]
\fill[gray!10] (1,1) rectangle (4,4);
\node[rotate=90,above,font=\small] at (1,2.5) {intensity};
\node[below,font=\small] at (2.5,1) {size};
\begin{scope}
\clip (1,1) rectangle (4,4);
% grid
\foreach \i in {1,2,...,4} 
    {
    \draw[gray!50] (\i,1) -- (\i,4);
    \draw[gray!50] (1,\i) -- (4,\i);
    }
% axis labels
\foreach \i in {2,3} 
    {
    \node[gray!50,above,fill=gray!10,font=\tiny,inner sep=2pt,yshift=2pt] at (\i,1) {\i};
    \node[gray!50,below,fill=gray!10,font=\tiny,inner sep=2pt,yshift=-2pt] at (\i,4) {\i};
    \node[gray!50,below,fill=gray!10,font=\tiny,inner sep=2pt,xshift=2pt,rotate=90] at (1,\i) {\i};
    \node[gray!50,above,fill=gray!10,font=\tiny,inner sep=2pt,xshift=-2pt,rotate=90] at (4,\i) {\i};
    }
% corner labels
\node[gray!50,above left,fill=gray!10,font=\tiny,inner sep=2pt,xshift=-2pt,rotate=90] at (4,4) {4};
\node[gray!50,below right,fill=gray!10,font=\tiny,inner sep=2pt,yshift=-2pt] at (1,4) {1};
\node[gray!50,above left,fill=gray!10,font=\tiny,inner sep=2pt,yshift=2pt] at (4,1) {4};
\node[gray!50,below right,fill=gray!10,font=\tiny,inner sep=2pt,xshift=2pt,rotate=90] at (1,1) {1};
\draw[line width=1pt] plot[smooth] file {testt.txt};
\draw[line width=1pt,red] plot[smooth] file {testp.txt};
\end{scope}
\draw[color=gray] (1,1) rectangle (4,4);
\end{tikzpicture}

\pgfplotsset{ % define your layer ordering
    /pgfplots/layers/pluton/.define layer set={
        axis background,axis grid,axis ticks,axis lines,axis tick labels,main,
        axis descriptions,axis foreground,
    }{/pgfplots/layers/standard},
}

\tikzset{pluton/.style={execute at end picture={%
    \begin{axis}[pluton second axis,#1]
    \end{axis}},
    /pgfplots/.cd,
    every axis/.append style={#1}}}
\pgfplotsset{pluton first axis/.style={axis background/.style={fill=gray!10},
    grid=major,pluton left labels,set layers=pluton,clip mode=individual,
    every axis plot/.append style={on layer=axis descriptions}},
    pluton left labels/.style={,axis y line*=left,axis x line*=left,
    xticklabel style={text=gray!50,fill=gray!10,font=\tiny,inner sep=2pt,anchor=south},
    yticklabel style={text=gray!50,fill=gray!10,font=\tiny,inner sep=2pt,anchor=west}},
    pluton right labels/.style={axis y line*=right,axis x line*=right,
    xticklabel style={text=gray!50,fill=gray!10,font=\tiny,inner sep=2pt,anchor=north},
    yticklabel style={text=gray!50,fill=gray!10,font=\tiny,inner sep=2pt,anchor=east},
    },pluton second axis/.style={width=\pgfkeysvalueof{/pgfplots/pluton/width},
    height=\pgfkeysvalueof{/pgfplots/pluton/height},pluton right labels},
    /pgfplots/pluton/.cd,
    xmin/.initial=0,xmax/.initial=1,ymin/.initial=0,ymin/.initial=1,
    width/.initial=10cm,height/.initial=10cm}
\begin{tikzpicture}[pluton={width=8cm,height=8cm,xmin=1,xmax=4,xtick={2,3},ymin=0.9,ymax=4.1,ytick={2,3}}]
\begin{axis}[pluton first axis,xlabel=size,ylabel=intensity]
 \addplot[line width=1pt,smooth] table {testt.txt};
 \addplot[line width=1pt,color=red,smooth] table {testp.txt};
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

7
  • Thank you, this looks very interesting. However, we still have to write xtick={2,3} by hand...
    – pluton
    Jun 17, 2019 at 14:35
  • @pluton Well, you did not provide a prescription from which it is clear where the grid lines should be. Are these always 3 cells in each direction or what?
    – user121799
    Jun 17, 2019 at 14:43
  • That was the meaning of "automatically", probably not so clear. So the idea was to use the default features of pgfplots (ie, no manual coding for the axis ticks) together with the new tick labeling stratey that you answered very nicely.
    – pluton
    Jun 17, 2019 at 14:48
  • @pluton You can leave xtick and ytick out, and then you will get pgfplots automatic solution. I added them to match your figure precisely.
    – user121799
    Jun 17, 2019 at 14:51
  • Ah I see. However, I just realized that your solution doe not add the "corner" labels. Why not?
    – pluton
    Jun 17, 2019 at 15:00

You must log in to answer this question.

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