%/=========================================================================\ %| | %| A Zoomorphic Nomogram | %| | %| Ron Doerfler | %| http://www.myreckonings.com/wordpress | %| Version: 02/21/08 | %| | %| This script plots a fish-shaped elliptic function nomogram as described | %| on the site listed above--please read the blog entry with this title. | %| It runs under the LaTeX typesetting software and uses the TikZ drawing | %| package that supports parametric plotting. I use the free MiKTeX | %| distribution of LaTeX (http://www.miktex.org) and the free TeXnicCenter | %| integrated development environment (IDE) running on top of it | %| (http://www.toolscenter.org/). Be sure to enable LaTeX to run an | %| an external program by adding --enable-write18 to the pdflatex command | %| line in the LaTeX=>PDF output profile to be selected in TeXnicCenter | %| (for some other installations this requires -shell-escape instead). | %| | %| TikZ parametric plots require GNUPLOT to be installed, which is freely | %| downloadable from http://www.gnuplot.info/. If you use the Windows | %| executable as I do, you must rename the executable from wgnuplot.exe | %| to gnuplot.exe and add its folder to the PATH environmental variable | %| of Windows so that TikZ can call it. | %| | %| LaTeX has a huge advantage over other ways of plotting nomograms such | %| as Excel or MatLab, both of which can graph parametric equations. | %| LaTeX provides great flexibility in the appearance of the plot, | %| including labeling the curves with the independent parameter which is | %| what is needed for reading a nomogram. | %| | %| All of this should sound familiar to anyone currently using LaTeX as a | %| typesetting tool for math or science articles. If you are unfamiliar | %| with LaTeX or have any questions at all about running this script, | %| please contact me using the Contact form at the URL at the top of this | %| header and I will be happy to help get you set up. | %| | %\=========================================================================/ % NOTE: There are 68 named colors: GreenYellow, Yellow, Goldenrod, Dandelion, % Apricot, Peach, Melon, YellowOrange, Orange, BurntOrange, Bittersweet, RedOrange, % Mahogany, Maroon, BrickRed, Red, OrangeRed, RubineRed, WildStrawberry, Salmon, % CarnationPink, Magenta, VioletRed, Rhodamine, Mulberry, RedViolet, Fuchsia, % Lavender, Thistle, Orchid, DarkOrchid, Purple, Plum, Violet, RoyalPurple, % BlueViolet, Periwinkle, CadetBlue, CornflowerBlue, MidnightBlue, NavyBlue, % RoyalBlue, Blue, Cerulean, Cyan, ProcessBlue, SkyBlue, Turquoise, TealBlue, % Aquamarine, BlueGreen, Emerald, JungleGreen, SeaGreen, Green, ForestGreen, % PineGreen, LimeGreen, YellowGreen, SpringGreen, OliveGreen, RawSienna, Sepia, % Brown,Tan,Gray % You can create custom colors as: \definecolor{myred}{rgb}{.7,0.3,0.45} % In the text you can use the colors as: \textcolor{myred}{This color is myred} \documentclass[11pt,landscape]{article} \usepackage{etex} % Support for >255 registers (counters, etc.) for values \usepackage{amsmath} % AMS math package \usepackage{amsfonts} % AMS math fonts \usepackage{amssymb} % AMS math symbols \usepackage[pdftex]{graphicx} % Adds options for graphics \usepackage[T1]{fontenc} % Use T1 font encoding \usepackage{mathptmx} % Times New Roman font as default \usepackage[pdftex,dvipsnames]{xcolor} % Extra foreground/background color support \usepackage{fullpage} % Sets all margins to 1 inch and the pagestyle to plain \usepackage{ifthen} % Provides ifthenelse construct \usepackage{tikz} % Drawing package \usetikzlibrary{shapes} % Adds diamond, ellipse, regular polygon, star, etc. \usetikzlibrary{snakes} % Adds snaking lines, coils, waves, saws, ticks, etc. \usetikzlibrary{topaths} % Adds from-to curves \usepackage{datatool} % Populate a database from external file and add/manipulate contents. \pagestyle{empty} % No page numbers \oddsidemargin -1.5cm \evensidemargin -1.5cm \topmargin -.25in \footskip -.5in \textheight 8in % My definitions. \newlength{\xvalue} \newlength{\yvalue} \newlength{\deltax} \newlength{\deltay} \newlength{\ticklength} \setlength{\ticklength}{1.5pt} \newlength{\gap} % Draw tick marks at input x,y coordinates and angles \newcommand{\tickmarks}{ \DTLloaddb{tickmarks}{uppertickmarks.csv} \DTLforeach*{tickmarks}{% \x=xcoord,\y=ycoord,\tickx=xscaled,\ticky=yscaled,\ticka=angle}{ \pgfmathparse{cos(\ticka)} \setlength{\deltax}{\pgfmathresult pt} \pgfmathparse{sin(\ticka)} \setlength{\deltay}{\pgfmathresult pt} % Point on upper curve \draw [line width=0.5pt,color=black](\tickx - \ticklength * \deltax,\ticky - \ticklength * \deltay) -- (\tickx + \ticklength * \deltax,\ticky + \ticklength * \deltay); % Matching point on lower curve (angle = 180 - upper angle) \draw [line width=0.5pt,color=black](\tickx - \ticklength * \deltax,-1.0 * \ticky + \ticklength * \deltay) -- (\tickx + \ticklength * \deltax,-1.0 * \ticky - \ticklength * \deltay); } } % Draw labels for upper W scale \newcommand{\drawupperw}{ \DTLloaddb{upperw}{W_upper.csv} \DTLforeach*{upperw}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=wvalue,\label=Weight,\ticka=angle}{ \draw (\xplot pt,\yplot pt) node[anchor=west,rotate=180.0 + \ticka] {\textcolor{OliveGreen}{\scriptsize \label}}; } } % Draw labels for upper T scale \newcommand{\drawuppert}{ \DTLloaddb{uppert}{T_upper.txt} \DTLforeach*{uppert}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=uvalue,\label=Temp,\ticka=angle}{ \draw (\xplot pt,\yplot pt) node[anchor=west,rotate=180.0 + \ticka] {\textcolor{red}{\scriptsize \hspace{18pt} \label}}; } } % Draw labels for upper 02 scale that matches upper T and upper W scales \newcommand{\drawupperupperO}{ \DTLloaddb{upperupperO}{OX_upper_upper.txt} \DTLforeach*{upperupperO}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=vvalue,\label=Oxygen,\ticka=angle}{ % Move labels around fins. \ifthenelse{\equal{\x}{-7}}{\setlength{\gap}{11pt}}{ \ifthenelse{\equal{\x}{-6}}{\setlength{\gap}{22pt}}{ \ifthenelse{\equal{\x}{-5}}{\setlength{\gap}{35pt}}{ \ifthenelse{\equal{\x}{-4}}{\setlength{\gap}{48pt}}{ \ifthenelse{\equal{\x}{-3}}{\setlength{\gap}{44pt}}{ \ifthenelse{\equal{\x}{-2}}{\setlength{\gap}{36pt}}{ \ifthenelse{\equal{\x}{-1}}{\setlength{\gap}{28pt}}{ \ifthenelse{\equal{\x}{0}}{\setlength{\gap}{22pt}}{\setlength{\gap}{0pt}} }}}}}}} \draw (\xplot pt,\yplot pt) node[anchor=east,rotate=180.0 + \ticka] {\textcolor{blue}{\scriptsize \label \hspace{\gap}}}; } } % Draw labels for lower 02 scale that matches upper T and upper W scales \newcommand{\drawupperlowerO}{ \DTLloaddb{upperlowerO}{OX_upper_lower.txt} \DTLforeach*{upperlowerO}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=vvalue,\label=Oxygen,\ticka=angle}{ % Move labels around fins. \ifthenelse{\equal{\x}{-12}}{\setlength{\gap}{11pt}}{ \ifthenelse{\equal{\x}{-11}}{\setlength{\gap}{21pt}}{ \ifthenelse{\equal{\x}{-4}}{\setlength{\gap}{8pt}}{ \ifthenelse{\equal{\x}{-3}}{\setlength{\gap}{18pt}}{ \ifthenelse{\equal{\x}{-2}}{\setlength{\gap}{24pt}}{ \ifthenelse{\equal{\x}{5}}{\setlength{\gap}{15pt}}{ \ifthenelse{\equal{\x}{6}}{\setlength{\gap}{28pt}}{ \ifthenelse{\equal{\x}{7}}{\setlength{\gap}{40pt}}{ \ifthenelse{\equal{\x}{8}}{\setlength{\gap}{47pt}}{ \ifthenelse{\equal{\x}{9}}{\setlength{\gap}{29pt}}{\setlength{\gap}{0pt}} }}}}}}}}} \draw (\xplot pt,\yplot pt) node[anchor=east,rotate=\ticka] {\textcolor{blue}{\scriptsize \label \hspace{\gap}}}; } } % Draw labels for lower W scale \newcommand{\drawlowerw}{ \DTLloaddb{lowerw}{W_lower.txt} \DTLforeach*{lowerw}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=wvalue,\label=Weight,\ticka=angle}{ \draw (\xplot pt,\yplot pt) node[anchor=east,rotate=180.0 + \ticka] {\textcolor{OliveGreen}{\scriptsize \label}}; } } % Draw labels for lower T scale \newcommand{\drawlowert}{ \DTLloaddb{lowert}{T_lower.txt} \DTLforeach*{lowert}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=uvalue,\label=Temp,\ticka=angle}{ \draw (\xplot pt,\yplot pt) node[anchor=east,rotate=180.0 + \ticka] {\textcolor{red}{\scriptsize \label \hspace{19pt}}}; } } % Draw labels for lower 02 scale that matches lower T and lower W scales \newcommand{\drawlowerlowerO}{ \DTLloaddb{lowerlowerO}{OX_lower_lower.txt} \DTLforeach*{lowerlowerO}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=vvalue,\label=Oxygen,\ticka=angle}{ % Move labels around fins. \ifthenelse{\equal{\x}{-12}}{\setlength{\gap}{27pt}}{ \ifthenelse{\equal{\x}{-11}}{\setlength{\gap}{37pt}}{ \ifthenelse{\equal{\x}{-4}}{\setlength{\gap}{24pt}}{ \ifthenelse{\equal{\x}{-3}}{\setlength{\gap}{34pt}}{ \ifthenelse{\equal{\x}{-2}}{\setlength{\gap}{40pt}}{ \ifthenelse{\equal{\x}{5}}{\setlength{\gap}{31pt}}{ \ifthenelse{\equal{\x}{6}}{\setlength{\gap}{44pt}}{ \ifthenelse{\equal{\x}{7}}{\setlength{\gap}{56pt}}{ \ifthenelse{\equal{\x}{8}}{\setlength{\gap}{63pt}}{ \ifthenelse{\equal{\x}{9}}{\setlength{\gap}{45pt}}{\setlength{\gap}{16pt}} }}}}}}}}} \draw (\xplot pt,\yplot pt) node[anchor=west,rotate=180.0 + \ticka] {\textcolor{black}{\scriptsize \hspace{\gap} \label}}; } } % Draw labels for upper 02 scale that matches lower T and lower W scales \newcommand{\drawlowerupperO}{ \DTLloaddb{lowerupperO}{OX_lower_upper.txt} \DTLforeach*{lowerupperO}{% \x=xcoord,\y=ycoord,\xplot=xscaled,\yplot=yscaled,\baselabel=vvalue,\label=Oxygen,\ticka=angle}{ % Move labels around fins. \ifthenelse{\equal{\x}{-7}}{\setlength{\gap}{27pt}}{ \ifthenelse{\equal{\x}{-6}}{\setlength{\gap}{38pt}}{ \ifthenelse{\equal{\x}{-5}}{\setlength{\gap}{51pt}}{ \ifthenelse{\equal{\x}{-4}}{\setlength{\gap}{64pt}}{ \ifthenelse{\equal{\x}{-3}}{\setlength{\gap}{60pt}}{ \ifthenelse{\equal{\x}{-2}}{\setlength{\gap}{52pt}}{ \ifthenelse{\equal{\x}{-1}}{\setlength{\gap}{44pt}}{ \ifthenelse{\equal{\x}{0}}{\setlength{\gap}{38pt}}{\setlength{\gap}{16pt}} }}}}}}} \draw (\xplot pt,\yplot pt) node[anchor=west,rotate=\ticka] {\textcolor{black}{\scriptsize \hspace{\gap} \label}}; } } \begin{document} \begin{center} % Add title. \Huge \textcolor{BrickRed}{\emph{\qquad \quad Oxygen Consumption Rate of Rainbow Trout}} \begin{tikzpicture} % Add space above picture with blank node. \draw[black] (-340pt,280pt) node[anchor=west] {\small}; % Add legend \draw[black] (-340pt,260pt) node[anchor=west] {\normalsize $O_2 = K T^n W^m$}; \draw[black] (-330pt,245pt) node[anchor=west] {\small $O_2$ = oxygen consumption rate in weight units of dissolved oxygen (DO) per 100 weight units of fish per day}; \draw[black] (-330pt,230pt) node[anchor=west] {\small $T$ = water temperature in degrees F}; \draw[black] (-330pt,215pt) node[anchor=west] {\small $W$ = average individual fish weight in lbs.}; \draw[black] (-330pt,200pt) node[anchor=west] {\small for $T>50$: $K=3.05\times10^{-4}$, $n=1.855$, $m=-0.138$}; \draw[black] (-330pt,185pt) node[anchor=west] {\small for $T^\prime<50$: $K=1.90\times10^{-6}$, $n=3.130$, $m=-0.138$}; \draw[black] (200pt,260pt) node[anchor=west] {\small Ron Doerfler}; %\draw[black] (200pt,270pt) node[anchor=west] {\small doerfpub@myreckonings.com}; \draw[black] (200pt,250pt) node[anchor=west] {\small http://www.myreckonings.com/wordpress}; % Draw axes and grid. Useful for construction, but commented out for final version. %\draw[gray,very thin,step=30pt] (-300pt,-200pt) grid (300pt,200pt); %\draw[line width=.5pt,->] (-300pt,0pt) -- (300pt,0pt) node[right] {\Large $x(t)$}; %\draw[line width=.5pt,->] (0pt,-200pt) -- (0pt,200pt) node[above] {\Large $y(t)$}; %\fill (0,0) circle (0.064cm); %\foreach \x in {-20, -18, ..., 20} % \pgfmathsetlength{\xvalue}{\x cm * .49209} % \draw (\xvalue,0pt) node[below] {\footnotesize \x} %; % Draw upper and lower halves of curve. % IMPORTANT: The TiKz plot command assumes cm as units, so the x and y scaling for % this plot command must equal the x and y scaling used in populating the input files % for the tick and lable coordinates, label divided by the number of points in 1 cm = 28.45 % The values used here assume the xscaling was 14pt and the yscaling was 0.70pt. \draw[color=black,domain=-20.135:24.0,xscale=.49209,yscale=0.024605,samples=2000,smooth] plot[id=nomogram1-q1] function{sqrt(4*x*x*x-1200.0*x+8500.0)}; \draw[color=black,domain=-20.135:24.0,xscale=.49209,yscale=0.024605,samples=2000,smooth] plot[id=nomogram1-q1] function{-sqrt(4*x*x*x-1200.0*x+8500.0)}; \draw[black] (-281.96pt,2.8pt) -- (-281.96pt,-2.8pt); % Draw fins. \draw[thin,rounded corners=4pt] (-112pt,88.68755pt) -- (-42pt,130pt) -- (14pt,80pt) -- (0pt,64.63678pt); \draw[thin,rounded corners=4pt] (-182pt,-86.6192pt) -- (-154pt,-115pt) -- (-147pt,-89.17pt); \draw[thin,rounded corners=4pt] (-70pt,-82.8251pt) -- (-21pt,-100pt) -- (-14pt,-68.9728pt); \draw[thin,rounded corners=4pt] (56pt,-44.0277pt) -- (126pt,-70pt) -- (133pt,-20pt) -- (126pt,-17.3735pt); \draw[out=240,in=145] (336pt,130.915pt) to (336pt,-130.915pt); \draw[black] (-168.5pt,-91.51pt) -- +(-96.03:6pt); \draw[black] (-154pt,-92.57pt) -- +(-92.87:19pt); \draw[black] (-55.3pt,-82.94pt) -- +(-77.6:4pt); \draw[black] (-41.2pt,-79.66pt) -- +(-76:14pt); \draw[black] (-27.3pt,-75.97pt) -- +(-74.6:22pt); \draw[black] (71.1pt,-41.34pt) -- +(-67.7:9pt); \draw[black] (85.1pt,-35.56pt) -- +(-67.7:22pt); \draw[black] (99pt,-29.86pt) -- +(-68.5:36pt); \draw[black] (112.9pt,-24.55pt) -- +(-71.3:40pt); \draw[black] (127pt,-21.37pt) -- +(-77.1:12pt); \draw[black] (-97.5pt,90.23pt) -- +(83:6pt); \draw[black] (-83.5pt,88.26pt) -- +(84.1:16pt); \draw[black] (-69.2pt,85.83pt) -- +(80.3:27pt); \draw[black] (-55pt,82.94pt) -- +(78.6:44pt); \draw[black] (-40.9pt,79.66pt) -- +(76:40pt); \draw[black] (-27pt,75.97pt) -- +(74.6:30pt); \draw[black] (-13pt,71.93pt) -- +(73.2:23pt); \draw[black] (1pt,68pt) -- +(72:17pt); % Draw eye. \filldraw[Tan] (-214pt,15pt) ellipse (15pt and 13pt); \filldraw[black] (-214pt,15pt) ellipse (9pt and 8pt); \filldraw[white] (-210pt,19pt) ellipse (2pt and 1.5pt); % Draw gill. \draw[BrickRed,line width=3pt,out=-30,in=10] (-170pt,45pt) to (-190pt,-40pt); \draw[black,line width=1pt,out=-30,in=10] (-170pt,45pt) to (-190pt,-40pt); % Draw mouth. %\draw[OliveGreen,line width=3pt,out=-10,in=160] (-280pt,-15.6525pt) to (-216pt,-30pt); %\draw[black,line width=1pt,out=-10,in=160] (-280pt,-15.6525pt) to (-216pt,-30pt); %\draw[OliveGreen,line width=3pt,out=30,in=190] (-275.8pt,-27.6345pt) to (-240pt,-25pt); %\draw[black,line width=1pt,out=30,in=190] (-275.8pt,-27.6345pt) to (-240pt,-25pt); % Plot tick marks and labels \tickmarks \drawupperw \drawuppert \drawupperupperO \drawupperlowerO \drawlowerw \drawlowert \drawlowerlowerO \drawlowerupperO % Label scales at end \draw (331pt,155pt) node[anchor=west,rotate=0] {\textcolor{blue}{\large $O_2$}}; \draw (352pt,130pt) node[anchor=west,rotate=0] {\textcolor{OliveGreen}{\large $W$}}; \draw (367pt,115pt) node[anchor=west,rotate=0] {\textcolor{red}{\large $T$}}; \draw (367pt,-115pt) node[anchor=west,rotate=0] {\textcolor{red}{\large $T^\prime$}}; \draw (352pt,-132pt) node[anchor=west,rotate=0] {\textcolor{OliveGreen}{\large $W^\prime$}}; \draw (319pt,-172pt) node[anchor=west,rotate=0] {\textcolor{black}{\large $O_2^\prime$}}; \end{tikzpicture} \end{center} \end{document}