3

I am using the following code. It compiles fine without the middle foreach statement, but fails with Undefined Control Sequence with it:

\documentclass[border=4pt]{standalone}
\usepackage{pgfplots}
\usepackage{tikz-3dplot}
\usepgfplotslibrary{colormaps,external}
\usetikzlibrary{calc,3d,arrows,shapes.geometric}

\pgfplotsset{compat=1.9}

\tdplotsetmaincoords{60}{150}%


\begin{document}

\begin{tikzpicture}[tdplot_main_coords]

\begin{axis}[
    axis equal,
    axis lines = center,
    width = 16cm,
    height = 16cm,
    xmin=-30,
    xmax=30,
    ymin=-30,
    ymax=30,
    zmin=-30,
    zmax=30,
    view/h=25,
]


    \foreach \t in {20}% generatrices
      \draw[yellow,thin,dashed] (axis cs: {0.75+0.75*cos(\t)},0,     
 {0.75*sin(\t)})
   --(axis cs: {0.75+0.75*cos(\t)},{-33.0},{0.75*sin(\t)});     


    \draw[yellow,thin,densely dotted] (axis cs: 1.5,-33,0)% lower circle
    \foreach \t in {5,10,...,360}
      {--(axis cs: {0.75+0.75*cos(\t)},-33,{0.75*sin(\t)})}--cycle;

    \draw[yellow,thin,densely dotted] (axis cs: 1.5,0,0)% upper circle
    \foreach \t in {5,10,...,360}
       {--(axis cs: {0.75+0.75*cos(\t)},0,{0.75*sin(\t)})}--cycle;



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

I added the {} around the nested draw statement. It doesn't seem obvious to me what the problem is.

EDIT: MWE provided (bad practice for not doing so!) with \t limited to one value but still failing to compile.

  • 1
    You have to put ; inside the brace, as the \draw is also inside. – Symbol 1 May 10 '17 at 16:56
  • But it failed before those {} were added also. – stars83clouds May 10 '17 at 16:58
  • But it is a good practice to use braces for \foreach! I personally do not use a single semicolon to terminate both \foreach and \draw. Remember the goto fail bug made by Apple? – Symbol 1 May 10 '17 at 17:09
  • Yes, I am aware of it. I re-tested your suggestion. It still falls flat. Without the \foreach and hard-coding a single angle compiles well. Do I need a \draw outside the \foreach? – stars83clouds May 10 '17 at 17:12
  • Well then... I ran out of ideas. You can either (a) wait for someone else; or (b) complete your code snippet by including both \documentcalss{xxx} and \end{document}. – Symbol 1 May 10 '17 at 17:14
  • 3
    @stars83clouds Can you please add a minimal code wrapper so we can play with it without having to guess? I get Package tikz Error: Unknown coordinate system 'axis'. – egreg May 10 '17 at 17:17
  • axis cs: is pgfplots. And https://tex.stackexchange.com/questions/170664/foreach-not-behaving-in-axis-environment ... – Rmano May 10 '17 at 17:24
  • @Symbol1, egreg - MWE provided above. Bad practice for not doing at the outset! – stars83clouds May 10 '17 at 17:39
  • @stars83clouds On my machine, exchanging \draw and \foreach does the trick. – Symbol 1 May 10 '17 at 17:43
  • @Symbol1 - What make is your machine? I'll go out and buy one! So you suggest putting the for-loop inside the draw statement? – stars83clouds May 10 '17 at 17:45
  • Yes, as you do not change the setting of \draw, letting \draw be outside is usually faster. – Symbol 1 May 10 '17 at 17:48
  • @Symbol1 - But that would work for one value, namely 20 degrees, to which I restricted it to in my testing. What if you wished to cycle through multiple values 0, 20, 40, etc? It would not be beneficial to have the \draw-statement outside then since only a single \draw-execution would be carried out. – stars83clouds May 10 '17 at 17:50
  • A single \draw can draw multiple subpaths. For example \draw(0,0)--(1,1)(2,2)--(3,3);. – Symbol 1 May 10 '17 at 17:53
  • I appreciate that. However, if you wished to draw say 20 lines, repeatably writing the clunky formula that I am invoking in the MWE above would make for a considerable task. Is there any way the \foreach could be utilized here? – stars83clouds May 10 '17 at 17:56
  • 1
    \draw[yellow,thin,dashed]foreach\t in{20,40,...,360}{(axis cs: {0.75+0.75*cos(\t)},0,{0.75*sin(\t)})--(axis cs: {0.75+0.75*cos(\t)},{-33.0},{0.75*sin(\t)})};. – Symbol 1 May 10 '17 at 17:56
  • Thanks @Symbol1! Works like a charm! You missed \ in \foreach. – stars83clouds May 10 '17 at 18:01
  • It is not necessary :) – Symbol 1 May 10 '17 at 18:03
  • @Symbol1 - Now I really do need that make of machine you have. It keeps complaining without the . Anyway, problem solved. Thanks! – stars83clouds May 10 '17 at 18:07

1 Answers1

3

If there is only one argument for the loop you can use \pgfplotsinvokeforeach inside axis:

  \pgfplotsinvokeforeach{20,40,...,360}{
    \draw[yellow,thin,dashed]
      (axis cs: {0.75+0.75*cos(#1)},0, {0.75*sin(#1)})
      --(axis cs: {0.75+0.75*cos(#1)},{-33.0},{0.75*sin(#1)});
  }

enter image description here

\documentclass[border=4pt]{standalone}
\usepackage{pgfplots}
\usepackage{tikz-3dplot}
\usepgfplotslibrary{colormaps,external}
\usetikzlibrary{calc,3d,arrows,shapes.geometric}

\pgfplotsset{compat=1.9}

\tdplotsetmaincoords{60}{150}%
\begin{document}
\begin{tikzpicture}[tdplot_main_coords]
\begin{axis}[
    axis equal,
    axis lines = center,
    width = 16cm,
    height = 16cm,
    xmin=-30,
    xmax=30,
    ymin=-30,
    ymax=30,
    zmin=-30,
    zmax=30,
    view/h=25,
]

  \pgfplotsinvokeforeach{20,40,...,360}{
    \draw[yellow,thin,dashed]
      (axis cs: {0.75+0.75*cos(#1)},0, {0.75*sin(#1)})
      --(axis cs: {0.75+0.75*cos(#1)},{-33.0},{0.75*sin(#1)});
  }

  \draw[yellow,thin,densely dotted] (axis cs: 1.5,-33,0)% lower circle
    \foreach \t in {5,10,...,360}
      {--(axis cs: {0.75+0.75*cos(\t)},-33,{0.75*sin(\t)})}--cycle;

  \draw[yellow,thin,densely dotted] (axis cs: 1.5,0,0)% upper circle
    \foreach \t in {5,10,...,360}
       {--(axis cs: {0.75+0.75*cos(\t)},0,{0.75*sin(\t)})}--cycle;
\end{axis}
\end{tikzpicture}
\end{document}

Note that pgfplots version 1.9 is really old. Current version is 1.14.

esdd
  • 85,675