3

I have been looking around the forum but did not find anything close to what I want to accomplish. I wanted to draw this nomogram used in control systems but just do not know where to begin. Can you help me draw this:

enter image description here

It seems to be generated from a z-plane grid of constant damping factors and natural frequencies

These are some forumlas:

enter image description here

enter image description here

Matlab has the z-grid command that plots this graph.

I have just started with the barebones environment:

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{amsmath} % Required for \varPsi below
\usetikzlibrary{tikzmark,calc,arrows,shapes,decorations.pathreplacing,pgfplots.groupplots}
\pgfplotsset{compat=newest, title/.append style={align =center}}
\tikzset{every picture/.style={remember picture}}

\begin{document}
\begin{tikzpicture}



\end{tikzpicture}
\end{document} 
5
  • 1
    Do you know the maths behind these lines? Googling "nomograph" and "control systems" doesn't show any similar result.
    – Ignasi
    Jun 1, 2017 at 12:20
  • I checked, but did not get much info. I'll keep looking around again and update my post. Thanks!
    – Joe
    Jun 1, 2017 at 12:25
  • For sure this can be done. But of course you need to have the data to do so. So either you have the equations of the lines or a data table/file. If you don't have at least of of them, you could "extract" the data from the graph e.g. by using markummitchell.github.io/engauge-digitizer. Jun 1, 2017 at 12:28
  • This I suppose is something that is closer to the Nicholas chart (in the control context). Jun 1, 2017 at 12:28
  • @Ignasi, I have updated some equations and Matlab plot function where this is generated. Hope this gives more help to a final convergence of the desired output?? Thanks for your time!
    – Joe
    Jun 1, 2017 at 18:38

2 Answers 2

8

Proposed grid options, to put in axis brackets:

  height=15cm,
  unit vector ratio = 1 1,
  xmin=-1.05,
  xmax=1.1,
  ymin=0,
  ymax=1.1,
  samples=100,
  %axis lines=center,
  %ticks=none,
  minor tick num=4,
  xtick distance=.25,
  ytick distance=.1,
  major grid style={thick},
  xticklabels={,-1,,-0.5,,0,,0.5,,1},
  yticklabels={,0,,0.2,,0.4,,0.6,,0.8,,1},
  grid=both,

Yielding

enter image description here

Clean version

enter image description here

\documentclass[12pt,tikz,border=2pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{polar}

\begin{document}
\begin{tikzpicture}
  \begin{axis}
    [
      height=15cm,
      unit vector ratio = 1 1,
      ymin=0,
      xmax=1.1,
      ymax=1.1,
      samples=100,
      axis lines=center,
      ticks=none,
    ]

    \pgfplotsinvokeforeach{0,...,9}
    {
      \def\zet{(.1*#1)}
      \pgfmathsetmacro{\factor}{\zet/sqrt(1-\zet^2)}
      \addplot[data cs=polar,domain=0:.35*sqrt(1-\zet^2)] (180*\x,{exp(-pi*\factor*\x})
          node[at end, sloped, anchor=south,font=\tiny, inner sep=0pt] {$\zeta{=}0.#1$};
      \addplot[data cs=polar,domain=.35*sqrt(1-\zet^2):sqrt(1-\zet^2)] (180*\x,{exp(-pi*\factor*\x});
    }

    \pgfplotsinvokeforeach{.1,.2,...,1}
    {
      \def\a{#1}
      \addplot[data cs=polar,domain=0:90] ({180*\a*cos(\x)},{exp(-pi*\a*sin(\x))});
    }
  \end{axis}
\end{tikzpicture}
\end{document}
4
  • Sincerest Thank you for all your time and help!
    – Joe
    Jun 5, 2017 at 2:00
  • Shall we finish the graph by adding the \zeta=1 line, adding axis labels and the nodes for \a? If you don't want to do it yourself, do you allow me to do it and edit your answer accordingly? Jun 5, 2017 at 10:33
  • @StefanPinnow Sure, go ahead and edit ! I didn't add nodes for the values of \a because 1. I didn't know what unknown to write. 2. using \foreach inside a pgfplots feels like esoterism to me. Furthermore, if you have a better solution than mine for placing the \zeta= nodes at 35% of the domain, I would be interested !
    – marsupilam
    Jun 5, 2017 at 10:56
  • @marsupilam, because I changed some more stuff than I first wanted to do, I decided to write this as a separate answer. And I think you have found the perfect way to add the ζ labels! Jun 6, 2017 at 20:14
2

This is basically the same answer as marsupilam's. The (main) differences are:

  • added $\zeta=1$ line
  • added $\omega$ labels
  • added axis labels
  • provided an alternative, more automated way to add the xticklabels and yticklabels

For more details please have a look at the comments in the code.

% used PGFPlots v1.14
\documentclass[12pt,border=2pt]{standalone}
\usepackage{pgfplots}
    % load the `polar' library so we can use `data cs=polar'
    \usepgfplotslibrary{polar}
    % use this `compat' level or higher to use the advanced axis label positioning
    \pgfplotsset{compat=1.3}
\begin{document}
\begin{tikzpicture}[
    % create a style for the common options of the labels
    Label/.style={
        font=\tiny,
        inner sep=1pt,
    },
]
    \begin{axis}[
        height=15cm,
        axis equal image=true,
        xmin=-1.05,
        xmax=1.05,
        ymin=0,
        ymax=1.05,
        xlabel=Real,
        ylabel=Imaginary,
        samples=61,             % <-- reduced number of samples and added `smooth'
        smooth,
        xtick distance=0.25,
        ytick distance=0.1,
        minor tick num=4,
        major grid style={thick},
        grid=both,
        % ---------------------------------------------------------------------
        % giving every second ticklabel manually ...
%        xticklabels={,-1,,-0.5,,0,,0.5,,1},
%        yticklabels={,0,,0.2,,0.4,,0.6,,0.8,,1},
        % ... and here an automatic way
        xticklabel={%
            \pgfmathsetmacro{\TickNum}{ifthenelse(mod(\ticknum,2)==0,1,0)}
            \ifdim\TickNum pt=0pt % a TeX \if -- see TeX Book
                $\pgfmathprintnumber{\tick}$%
            \else
            \fi
        },
        yticklabel={%
            \pgfmathsetmacro{\TickNum}{ifthenelse(mod(\ticknum,2)==0,1,0)}
            \ifdim\TickNum pt=0pt % a TeX \if -- see TeX Book
                $\pgfmathprintnumber{\tick}$%
            \else
            \fi
        },
        % ---------------------------------------------------------------------
        data cs=polar,          % <-- moved common `addplot' options here
        clip=false,             % <-- added so the labels aren't clipped
    ]

        % constant $\zeta$ contours
        % (we cannot also calculate the $\zeta = 1$ line directly, because
        %  this will lead to a "division by zero" error)
        % the lines will be plotted in two parts to place the labels at
        % a "good" position
        % (because we want to add them `sloped' it is not an option to add
        %  the nodes separately at the calculated positions)
        \pgfplotsinvokeforeach{0,0.1,...,0.9} {
                % calculate a factor in advance
                \pgfmathsetmacro{\factor}{#1/sqrt(1-#1^2)}
            % plot the first part of the $\zeta$ contour lines ...
            \addplot [
                domain=0:0.35*sqrt(1-#1^2),
            ] (180*x,{exp(-pi*\factor*x)})
                % ... and add the labels
                node [
                    Label,
                    at end,
                    sloped,
                    anchor=south,
                ] {$\zeta =
                    % because of some math inaccuracies we need to format the
                    % numbers when we use the `\pgfmathprintnumber'
                    \pgfmathprintnumber[
                        fixed,
                        fixed zerofill,
                        precision=1,
                    ]{#1}$
                }
            ;
            % plot the second part of the $\zeta$ contour lines
            \addplot [
                domain=.35*sqrt(1-#1^2):sqrt(1-#1^2),
            ] (180*x,{exp(-pi*\factor*x)});
        }

        % now add the $\zeta = 1$ line
        \addplot [
            domain=exp(-pi):1,
            samples=2,
            data cs=cart,
        ] (x,0)
            node [
                Label,
                pos=0.31,       % <-- found due to testing
                anchor=south,
            ] {$\zeta = 1$}
        ;

        % constant $\omega$ contours
        \pgfplotsinvokeforeach{0.05,0.1,0.2,...,1.0} {
            \addplot [
                domain=0:90,
            ] ({180*#1*cos(x)},{exp(-pi*#1*sin(x))})
                % add the nodes again
                node [
                    Label,
                    at start,
                    anchor=180*(#1-1),
                ] {%
                      % we don't want to plot the "1" so we need a special
                      % handler
                      % (unfortunately `\pgfmathprintnumber' seems to *need*
                      %  to have a number and thus we cannot do something
                      %  like
                      %     \pgfmathparse{ifthenelse(abs(#1-1)<0.01,,#1)}%
                      %     $\frac{\pgfmathprintnumber[fixed]{#1}\,\pi}{T}$
                      % )
                      \ifdim#1 pt>0.99pt
                          $\frac{\pi}{T}$
                      \else
                          $\frac{\pgfmathprintnumber[fixed]{#1}\,\pi}{T}$
                      \fi
                  }
            ;
        }
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

2
  • Ok, you're not the lazy type, are you ? ;) Glad I "let" you do the work ! Thanks, I will look into it.
    – marsupilam
    Jun 6, 2017 at 20:30
  • 1
    @marsupilam, not really. But honestly: You did the great start and -- as I already mentioned in the comment to your answer -- you found the great solution for positioning the ζ labels, which I would have never come up with. I just gave your solution some "finishing". Jun 6, 2017 at 20:31

You must log in to answer this question.

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