4

I've been writing a set of simple line drawing macros for some piecewise functions. For some reason, when I attempt to add color to the lines, each segment is translated to the right.

I've verified that this is not because of a shared variable name, and placed a MWE below, along with the output. Removing the \color statement from the \drawthedamnline macro yields the correct output (the line segments are contiguous). My suspicion is that this has something to do with the way I've written the macros. Any advise would be helpful.

\documentclass[12pt]{article}

\usepackage[nomessages]{fp}
\usepackage{color}
\usepackage{wrapfig}
\usepackage{amsmath}
\usepackage{ifthen}

\newcommand{\ticks}[5]{ %x,y,numticks,direction (x=0,y=1),tickwidth
    \ifthenelse{#3=0}{

    }
    {
        \ifthenelse{#4=0}{
            \FPadd{\newx}{#1}{#5}
            \FPset{\newy}{#2}
            \put(\newx,\newy){\line(0,1){5}}
        }
        {
            \FPset{\newx}{#1}
            \FPadd{\newy}{#2}{#5}
            \put(\newx,\newy){\line(1,0){5}}
        }
        \FPsub{\numticksleft}{#3}{1}
        \FPclip{\numticksleft}{\numticksleft}
        \ticks{\newx}{\newy}{\numticksleft}{#4}{#5}
    }
}


\newcommand{\peakplot}[5]{ %x,y,height,width,num_candidates
   \put(#1,#2){\vector(0,1){#3}}
   \put(#1,#2){\vector(1,0){#4}}
    \FPsub{\tickspacex}{#3}{10}
    \FPsub{\tickspacey}{#4}{10}
    \FPdiv{\tickwidth}{\tickspacex}{#5}
    \FPclip{\tickwidth}{\tickwidth}
   \ticks{#1}{#2}{#5}{1}{\tickwidth}
    \FPdiv{\tickwidth}{\tickspacey}{#5}
   \ticks{#1}{#2}{#5}{0}{\tickwidth}
}

\newcommand{\drawthedamnline}[1]{
        \color{\mylinecolor}
        \put(\mypeakx, \peaky){\line(1,#1){\peakspace}}
}

\newcommand{\plotpeaks}[1]{ %used by \peak to plot a peak.
        \drawthedamnline{#1}
        \FPadd{\mypeakx}{\mypeakx}{\peakspace}
        \FPmul{\ymove}{\peakspace}{#1}
        \FPadd{\peaky}{\ymove}{\peaky}
        \ifthenelse{\numpeaks=1}{}{
            \FPsub{\numpeaks}{\numpeaks}{1}
            \FPclip{\numpeaks}{\numpeaks}
            \plotpeaks
        }
}
\newcommand{\peak}[5]{ %x,y, num_args, width, color, arg1, arg2,...argn.
    \FPset{\mypeakx}{#1}
    \FPset{\peaky}{#2}
    \FPset{\numpeaks}{#3}
    \FPdiv{\peakspace}{#4}{#3}
    \FPclip{\peakspace}{\peakspace}
    \def \mylinecolor {#5}
    \plotpeaks
}

\begin{document}


\begin{wrapfigure}{r}{0.33\textwidth}
  \begin{center}
    \begin{picture}(100,100)
        \thicklines
        \peakplot{0}{0}{100}{100}{5}
        \peak{0}{0}{5}{90}{red}{1}{1}{1}{1}{1}
        \peak{0}{90}{5}{90}{blue}{-1}{-1}{-1}{-1}{-1}
        \peak{0}{0}{5}{90}{green}{2}{1}{2}{-1}{-1}
    \end{picture}
  \end{center}
  \caption{}
  \label{condorcetFig}
\end{wrapfigure}

\end{document}

enter image description here

  • 1
    The color command defeats picture modes attempt to remove extra space. It is best if you don't put the extra space in in teh first place (see egreg's answer, but if you put the color inside the \put text rather than before it as in Harish's answer the color whatsit will appear in a safer place. So you could do both:-) – David Carlisle Nov 28 '13 at 22:47
5

You have loads of unprotected end-of-lines that could produce a space in output.

\documentclass[12pt]{article}

\usepackage[nomessages]{fp}
\usepackage{color}
\usepackage{wrapfig}
\usepackage{amsmath}
\usepackage{ifthen}

\newcommand{\ticks}[5]{%x,y,numticks,direction (x=0,y=1),tickwidth
  \ifthenelse{#3=0}
    {}%
    {%
     \ifthenelse{#4=0}
       {%
        \FPadd{\newx}{#1}{#5}%
        \FPset{\newy}{#2}%
        \put(\newx,\newy){\line(0,1){5}}%
       }%
       {%
        \FPset{\newx}{#1}%
        \FPadd{\newy}{#2}{#5}%
        \put(\newx,\newy){\line(1,0){5}}%
       }%
    \FPsub{\numticksleft}{#3}{1}%
    \FPclip{\numticksleft}{\numticksleft}%
    \ticks{\newx}{\newy}{\numticksleft}{#4}{#5}%
   }%
}


\newcommand{\peakplot}[5]{%x,y,height,width,num_candidates
  \put(#1,#2){\vector(0,1){#3}}%
  \put(#1,#2){\vector(1,0){#4}}%
  \FPsub{\tickspacex}{#3}{10}%
  \FPsub{\tickspacey}{#4}{10}%
  \FPdiv{\tickwidth}{\tickspacex}{#5}%
  \FPclip{\tickwidth}{\tickwidth}%
  \ticks{#1}{#2}{#5}{1}{\tickwidth}%
  \FPdiv{\tickwidth}{\tickspacey}{#5}%
  \ticks{#1}{#2}{#5}{0}{\tickwidth}%
}

\newcommand{\drawthedamnline}[1]{%
  \color{\mylinecolor}%
  \put(\mypeakx, \peaky){\line(1,#1){\peakspace}}%
}

\newcommand{\plotpeaks}[1]{%used by \peak to plot a peak.
  \drawthedamnline{#1}%
  \FPadd{\mypeakx}{\mypeakx}{\peakspace}%
  \FPmul{\ymove}{\peakspace}{#1}%
  \FPadd{\peaky}{\ymove}{\peaky}%
  \ifthenelse{\numpeaks=1}
    {}
    {%
     \FPsub{\numpeaks}{\numpeaks}{1}%
     \FPclip{\numpeaks}{\numpeaks}%
     \plotpeaks
    }%
}
\newcommand{\peak}[5]{%x,y, num_args, width, color, arg1, arg2,...argn.
  \FPset{\mypeakx}{#1}%
  \FPset{\peaky}{#2}%
  \FPset{\numpeaks}{#3}%
  \FPdiv{\peakspace}{#4}{#3}%
  \FPclip{\peakspace}{\peakspace}%
  \def\mylinecolor{#5}%
  \plotpeaks
}

\begin{document}


\begin{wrapfigure}{r}{0.33\textwidth}
  \begin{center}
    \begin{picture}(100,100)
        \thicklines
        \peakplot{0}{0}{100}{100}{5}%
        \peak{0}{0}{5}{90}{red}{1}{1}{1}{1}{1}%
        \peak{0}{90}{5}{90}{blue}{-1}{-1}{-1}{-1}{-1}%
        \peak{0}{0}{5}{90}{green}{2}{1}{2}{-1}{-1}%
    \end{picture}
  \end{center}
  \caption{}
  \label{condorcetFig}
\end{wrapfigure}

\end{document}

enter image description here

  • Thanks! Accepted as it provides an explanation for the problem. Harish's solution below also seems excellent practice however! – John Doucette Nov 29 '13 at 14:01
5

Put \color{mylinecolor} inside:

\newcommand{\drawthedamnline}[1]{%     %% <---Spurious space
        %\color{\mylinecolor}
        \put(\mypeakx, \peaky){\color{\mylinecolor}\line(1,#1){\peakspace}}
}

Full code:

\documentclass[12pt]{article}

\usepackage[nomessages]{fp}
\usepackage{color}
\usepackage{wrapfig}
\usepackage{amsmath}
\usepackage{ifthen}

\newcommand{\ticks}[5]{%x,y,numticks,direction (x=0,y=1),tickwidth
    \ifthenelse{#3=0}{
    }
    {
        \ifthenelse{#4=0}{
            \FPadd{\newx}{#1}{#5}
            \FPset{\newy}{#2}
            \put(\newx,\newy){\line(0,1){5}}
        }
        {
            \FPset{\newx}{#1}
            \FPadd{\newy}{#2}{#5}
            \put(\newx,\newy){\line(1,0){5}}
        }
        \FPsub{\numticksleft}{#3}{1}
        \FPclip{\numticksleft}{\numticksleft}
        \ticks{\newx}{\newy}{\numticksleft}{#4}{#5}
    }
}


\newcommand{\peakplot}[5]{%x,y,height,width,num_candidates
   \put(#1,#2){\vector(0,1){#3}}
   \put(#1,#2){\vector(1,0){#4}}
    \FPsub{\tickspacex}{#3}{10}
    \FPsub{\tickspacey}{#4}{10}
    \FPdiv{\tickwidth}{\tickspacex}{#5}
    \FPclip{\tickwidth}{\tickwidth}
   \ticks{#1}{#2}{#5}{1}{\tickwidth}
    \FPdiv{\tickwidth}{\tickspacey}{#5}
   \ticks{#1}{#2}{#5}{0}{\tickwidth}
}

\newcommand{\drawthedamnline}[1]{%
        %\color{\mylinecolor}
        \put(\mypeakx, \peaky){\color{\mylinecolor}\line(1,#1){\peakspace}}
}

\newcommand{\plotpeaks}[1]{%used by \peak to plot a peak.
        \drawthedamnline{#1}
        \FPadd{\mypeakx}{\mypeakx}{\peakspace}
        \FPmul{\ymove}{\peakspace}{#1}
        \FPadd{\peaky}{\ymove}{\peaky}
        \ifthenelse{\numpeaks=1}{}{
            \FPsub{\numpeaks}{\numpeaks}{1}
            \FPclip{\numpeaks}{\numpeaks}
            \plotpeaks
        }
}
\newcommand{\peak}[5]{ %x,y, num_args, width, color, arg1, arg2,...argn.
    \FPset{\mypeakx}{#1}
    \FPset{\peaky}{#2}
    \FPset{\numpeaks}{#3}
    \FPdiv{\peakspace}{#4}{#3}
    \FPclip{\peakspace}{\peakspace}
    \def \mylinecolor {#5}
    \plotpeaks
}

\begin{document}


\begin{wrapfigure}{r}{0.33\textwidth}
  \begin{center}
    \begin{picture}(100,100)
        \thicklines
        \peakplot{0}{0}{100}{100}{5}
        \peak{0}{0}{5}{90}{red}{1}{1}{1}{1}{1}
        \peak{0}{90}{5}{90}{blue}{-1}{-1}{-1}{-1}{-1}
        \peak{0}{0}{5}{90}{green}{2}{1}{2}{-1}{-1}
    \end{picture}
  \end{center}
  \caption{}
  \label{condorcetFig}
\end{wrapfigure}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.