1

I need to have my x-labels in my pgfplots to be vector graphics. How can I prevent the graphical x-labels from streching?

In below is a MWE that can duplicate my problem. The drawn rectangles and circles are stretched and distorted below the x-axis (the circles became ellipses).

I am looking for a way such that the aspect ratio of graphical labels become insensitive to the size of the axis similar to the way numbers are printed as axis labels, i.e., xticklabels={0, 90, 180, 270, 360}. No matter what the size of the axis is, the result will come out very nice with the correct and proper aspect ratio if the xticklabels are just numbers. I want to be able to have the same thing when I am using graphics as xticklabels instead of plain numbers/texts.

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usepackage{tkz-euclide}  
\usetikzlibrary{patterns}
\begin{filecontents*}{data.csv}
    a,b,c
    0,4,1
    90,3,2
    180,5,3
    270,1,4
    360,3,5
\end{filecontents*}

\newcommand{\mL}{5}
\newcommand{\mW}{30}

\pgfplotsset{compat=newest,height = 10cm, width = 20cm}

\pgfplotsset{minor grid style={dotted}}


\newcommand{\myGfxLabels}[1]
    {
        \begin{tikzpicture}
            \tkzDefPoint( {\mL},-{\mW}){B};
            \foreach \xDelta in {0}
            {
                \draw[->,line width=1pt,rotate={0},red] ({\mL+\xDelta}, -{1.5*\mW}) -- ({\mL+\xDelta},-{\mW});
            } 
            \draw[fill=red!50!yellow,pattern=north east lines,shift={(0 cm,0 cm)},rotate around={-#1:(B)},xscale=1,yscale=1,] ({\mL}, {\mW}) -- ({\mL},-{\mW}) -- (-{\mL},-{\mW}) -- (-{\mL},{\mW}) -- ({\mL}, {\mW});
            \draw[] (B) circle ({\mL});
        \end{tikzpicture}
    }



\begin{document}
    \begin{tikzpicture}
    \begin{axis}
        [   
            xlabel={$\phi$},
            ylabel={$dL_{\rm cavity}$},
            xtick={0, 90, 180, 270, 360},
            xticklabels={\myGfxLabels{0}, \myGfxLabels{90}, \myGfxLabels{180}, \myGfxLabels{270}, \myGfxLabels{360}},
            smooth,
            grid=both,
            minor tick num=2,
            title={Title},
        ]
        \addplot+ table [x=a, y=b,col sep=comma] {data.csv};


    \end{axis}
    \end{tikzpicture}
\end{document}

enter image description here

Torbjørn T.
  • 206,688
  • 1
    Nesting tikzpictures often leads to problems. A workaround is to use the standalone class to create a PDF containing the images, and then use \includegraphics in the ticklabels. (I only get a Dimension too large error from your code, by the way.) – Torbjørn T. Jun 16 '16 at 05:47
  • @Torbjorn T. I am able to compile the code with no problem, I have no idea why it does not on your. Regarding making a pdf, unfortunately, this example is a simple version of what I want to do. There will be many graphics that I need to generate and it would be a pain. I am trying to find a solution that freezes or suspend the graphics from being distorted. – shashashamti2008 Jun 16 '16 at 06:04
  • Me neither, perhaps version differences. As a wild guess, you can try adding disabledatascaling to the axis options. (If I do that the code compiles, but I don't get any ticklabels at all.) – Torbjørn T. Jun 16 '16 at 06:09
  • Using disabledatascaling didn't help. There should be a way around this problem, looks solvable! I also checked some of the solutions here: http://tex.stackexchange.com/questions/4338/correctly-scaling-a-tikzpicture. No success so far. I was hopeful that \resizebox can fix the issue, but I was wrong. I don't know, maybe I am not using them correctly. – shashashamti2008 Jun 16 '16 at 06:27
  • Not sure what you're aiming for, but does adding [x=1pt,y=1pt] to the tikzpicture for the x-tick label picture inside \myGfxLabels achieve the desired result? – Mark Wibrow Jun 16 '16 at 10:11
  • Presumably you want some scaling, as \myGfxLabels is huge by itself. IIRC, the default is to use the (axis cs: x,y) so to draw a circle you actually need to draw an ellipse. – John Kormylo Jun 16 '16 at 13:44

1 Answers1

2

The best way to combine graphics and plots is to save the coordinates inside the axis environment then draw the graphics outside. I adjusted \mL, \mW, and yshift to fit.

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
%\usepackage{tkz-euclide}
\usetikzlibrary{patterns}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
    a,b,c
    0,4,1
    90,3,2
    180,5,3
    270,1,4
    360,3,5
\end{filecontents*}

\newcommand{\mL}{.1}
\newcommand{\mW}{.6}

\newlength{\xshift}

\pgfplotsset{compat=newest,height = 10cm, width = 20cm}

\pgfplotsset{minor grid style={dotted}}


\newcommand{\myGfxLabels}[2]% #1=x, #2=anchor
    {
        \pgfextractx{\xshift}{\pgfpointanchor{#2}{center}}%
        \begin{scope}[xshift=\xshift,yshift={-\mW cm}]
            \coordinate (B) at ( {\mL},-{\mW});
            \foreach \xDelta in {0}
            {
                \draw[->,line width=1pt,rotate={0},red] ({\mL+\xDelta}, -{1.5*\mW}) -- ({\mL+\xDelta},-{\mW});
            } 
            \draw[fill=red!50!yellow,pattern=north east lines,shift={(0 cm,0 cm)},rotate around={-#1:(B)}] ({\mL}, {\mW}) -- ({\mL},-{\mW}) -- (-{\mL},-{\mW}) -- (-{\mL},{\mW}) -- ({\mL}, {\mW});
            \draw[] (B) circle ({\mL});
        \end{scope}
    }

\begin{document}

    \begin{tikzpicture}
    \begin{axis}
        [   
            xlabel={$\phi$},
            ylabel={$dL_{\rm cavity}$},
            xtick={0, 90, 180, 270, 360},
            xticklabels=\empty,
            smooth,
            grid=both,
            minor tick num=2,
            title={Title},
        ]
        \addplot+ table [x=a, y=b,col sep=comma] {data.csv};
        \coordinate (tick0) at (0,0);
        \coordinate (tick90) at (90,0);
        \coordinate (tick180) at (180,0);
        \coordinate (tick270) at (270,0);
        \coordinate (tick360) at (360,0);
    \end{axis}
    \myGfxLabels{0}{tick0}
    \myGfxLabels{90}{tick90}
    \myGfxLabels{180}{tick180}
    \myGfxLabels{270}{tick270}
    \myGfxLabels{360}{tick360}

    \end{tikzpicture}
\end{document}

demo

John Kormylo
  • 79,712
  • 3
  • 50
  • 120