5

How might I change this macro to place the mixed numbers underneath the number line?

In this particular example, I'd like 1 1/4, 1 2/4, 1 3/4, 2 1/4, etc.

Dunno if this needs a separate thread, but is there any way the macro could have the option to either include or not include those mixed numbers?

I know this isn't a truly minimal working example, but I think it makes the context much clearer.

\documentclass{article}
\usepackage{tikz}

\newcommand{\NL}[5]
{\tikz[xscale=#1,yscale=#2]
 {
 \filldraw[orange] (0,0) rectangle (#5,0.2); %shaded portion of number line
 \draw
  (0,0)--(#3,0) %lower part of x-axis
  (0,0.2)--(#3,0.2); %higher part of x-axis
 \foreach \x in {0,...,#3}
  \node[below] at (\x,-0.2) {\x}; %whole numbers underneath number line
  \pgfmathparse{#3*#4}
 \foreach \x in {0,...,\pgfmathresult} %fractional tick marks and numbers above number line
  {
   \draw (\x/#4,-0.2)--(\x/#4,0.2);
   \node[above] at (\x/#4,0.25) {$\frac{\x}{#4}$};
  }
 \fill[green,opacity=0.75] (#5,0.1) circle[x radius=0.2cm/#1,y radius=0.2cm/#2]; %green dot
 }
}

\begin{document}

Draw and label a number line from 0 to 3 with tick marks at every quarter, emphasizing \(\frac{7}{4}=1\frac{3}{4}\). Show your answer using both a length and a point.

\NL{4}{1.2}{3}{4}{7/4}
%{x-scale}{y-scale}{from 0 to 3}{denominator}{emphasized point}
\end{document}

That code yields this:

number line macro

1 Answers1

5

Perhaps something like this?

\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{xparse}
% ref: WeCanLearnAnything at http://tex.stackexchange.com/questions/267921/macro-for-mixed-numbers-on-number-line-tikz (but I doubt this is the original source)
\NewDocumentCommand\NL { s m m m m m }
{\tikz[xscale=#2,yscale=#3]
 {
 \filldraw[orange] (0,0) rectangle (#6,0.2);% shaded portion of number line
 \draw
  (0,0)--(#4,0)% lower part of x-axis
  (0,0.2)--(#4,0.2);% higher part of x-axis
 \foreach \x in {0,...,#4}
  \node [anchor=mid] at (\x,-0.5) {\x};% whole numbers underneath number line
  \pgfmathparse{#4*#5}
 \foreach \x in {0,...,\pgfmathresult}% fractional tick marks and numbers above number line
  {
   \draw (\x/#5,-0.2)--(\x/#5,0.2);
   \node[above] at (\x/#5,0.25) {$\frac{\x}{#5}$};
   \IfBooleanF {#1}{
     \pgfmathsetmacro\intbit{int(\x/#5)}
     \pgfmathsetmacro\fracbit{int(\x-#5*\intbit)}
     \ifnum\intbit=0\let\intbit\relax\fi
     \ifnum\fracbit=0\else
     \node [anchor=mid] at (\x/#5,-0.5) {$\intbit\frac{\fracbit}{#5}$};
     \fi
   }
  }
 \fill[green,opacity=0.75] (#6,0.1) circle[x radius=0.2cm/#2,y radius=0.2cm/#3];% green dot
 }
}

\begin{document}

\NL{4}{1.2}{3}{4}{7/4}
\NL*{4}{1.2}{3}{4}{7/4}

\end{document}

now you see them - now you don't

New Interface

However, I would be tempted to rethink the user interface. It will get hard to remember how many arguments you need and which one is which pretty quickly. Plus, it would be nice to be able to vary some other aspects of the line: the colour of the dot and the fill, the dot's opacity and so on.

To achieve this, you can use a key-value interface. Since you are already using TikZ, using its key management is probably sensible.

I would also configure the commands so that you can include a number line - or several - into a larger picture, and so that you have as much flexibility as possible in setting the keys.

Here's a rough draft which could surely be fine-tuned in various ways:

  • \tnl creates a number line within a TikZ picture so \tikz\tnl; will draw the line as a standalone picture;

  • number line={<number line settings>} is a TikZ option which can be set in the usual way e.g. \begin{tikzpicture}[number line={<number line settings>}] or \tikzset{number line={<number line settings>}} etc. Default settings are based on your MWE. It sets the various attributes of the number line:

    • fraction=<opt> denominator (4)
    • v scale=<opt> to scale vertically (1.2)
    • h scale=<opt> to scale horizontally (4)
    • max=<opt> highest number (3)
    • number to=<opt> fill line to ({7/4})
    • mixed numbers=<opt> print mixed numbers (false)
    • fill=<opt> fill line colour (orange)
    • dot=<opt> dot colour (green)
    • dot opacity=<opt> dot opacity (.75)
  • \NumberLine*[<number line settings>] is intended for use outside a TikZ environment and creates a standalone number line. The starred version does not print the mixed numbers.

First, reproduce the output from the earlier code, just using the defaults, to check the output matches:

\NumberLine

number line

\NumberLine*

number line

A number line with some non-defaults settings:

\NumberLine[
  dot=red,
  dot opacity=.5,
  fill=blue,
  fraction=3,
  number to={2/3},
  h scale=5,
]

number line

Let's change the defaults:

\tikzset{
  number line={
    fraction=5,
    mixed numbers=true,
    number to={8/5},
    h scale=2,
    v scale=1.25,
    max=6,
  }
}

and try combining two number lines into one picture:

\begin{tikzpicture}
  \tnl;
  \begin{scope}[yshift=-30mm]
    \tnl;
  \end{scope}
\end{tikzpicture}

number line x 2

Complete Code:

\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{xparse}
\makeatletter
\newif\ifnl@mixednumbers
\tikzset{% http://tex.stackexchange.com/a/159856/ - Claudio Fiandrino
  number line/.code={
    \tikzset{
      /number line/.cd,%
      #1
    }
  },
  /number line/.cd,
  fraction/.store in=\nl@fraction,
  v scale/.store in=\nl@vscale,
  h scale/.store in=\nl@hscale,
  max/.store in=\nl@max,
  number to/.store in=\nl@numberto,
  mixed numbers/.is if=nl@mixednumbers,
  fill/.store in=\nl@fill,
  dot/.store in=\nl@dot,
  dot opacity/.store in=\nl@dotopacity,
  fraction=4,
  v scale=1.2,
  h scale=4,
  max=3,
  number to={7/4},
  mixed numbers=false,
  fill=orange,
  dot=green,
  dot opacity=.75,
}
\newcommand*\tnl{% modified from ref: WeCanLearnAnything at http://tex.stackexchange.com/questions/267921/macro-for-mixed-numbers-on-number-line-tikz (but I doubt this is the original source)
  \begin{scope}[xscale=\nl@hscale,yscale=\nl@vscale]
    \filldraw[\nl@fill] (0,0) rectangle (\nl@numberto,0.2);% shaded portion of number line
    \draw
    (0,0)--(\nl@max,0)% lower part of x-axis
    (0,0.2)--(\nl@max,0.2);% higher part of x-axis
    \foreach \x in {0,...,\nl@max}
      \node [anchor=mid] at (\x,-0.5) {\x};% whole numbers underneath number line
    \pgfmathparse{\nl@max*\nl@fraction}
    \foreach \x in {0,...,\pgfmathresult}% fractional tick marks and numbers above number line
    {
      \draw (\x/\nl@fraction,-0.2)--(\x/\nl@fraction,0.2);
      \node[above] at (\x/\nl@fraction,0.25) {$\frac{\x}{\nl@fraction}$};
      \ifnl@mixednumbers
        \pgfmathsetmacro\intbit{int(\x/\nl@fraction)}
        \pgfmathsetmacro\fracbit{int(\x-\nl@fraction*\intbit)}
        \ifnum\intbit=0\let\intbit\relax\fi
        \ifnum\fracbit=0\else
          \node [anchor=mid] at (\x/\nl@fraction,-0.5) {$\intbit\frac{\fracbit}{\nl@fraction}$};
        \fi
      \fi
    }
    \fill[\nl@dot,opacity=\nl@dotopacity] (\nl@numberto,0.1) circle[x radius=0.2cm/\nl@hscale,y radius=0.2cm/\nl@vscale];% green dot
  \end{scope}}
\NewDocumentCommand \NumberLine { s O {} }{%
  \IfBooleanTF {#1}{%
    \tikz[number line={mixed numbers=false,#2}]\tnl;%
  }{%
    \tikz[number line={mixed numbers=true,#2}]\tnl;%
  }}
\makeatother

\begin{document}

\NumberLine

\NumberLine*

\NumberLine[
  dot=red,
  dot opacity=.5,
  fill=blue,
  fraction=3,
  number to={2/3},
  h scale=5,
]

\tikzset{
  number line={
    fraction=5,
    mixed numbers=true,
    number to={8/5},
    h scale=2,
    v scale=1.25,
    max=6,
  }
}
\begin{tikzpicture}
  \tnl;
  \begin{scope}[yshift=-30mm]
    \tnl;
  \end{scope}
\end{tikzpicture}

\end{document}
cfr
  • 198,882
  • Wow, this looks amazing. It will probably take me a while to make sense of it. I'm going to read it more in depth tomorrow and post more here afterwards. – WeCanLearnAnything Sep 17 '15 at 09:09
  • Wow again! This is a lot to internalize. Do you think this is worth me trying to understand it or should I just copy the code and paint by numbers? – WeCanLearnAnything Sep 20 '15 at 06:36
  • @WeCanLearnAnything That's up to you ;). Me, I would try to understand it and ask about anything I couldn't figure out. I have a couple of strategies for this. One is to look stuff up in the manual. The other is to alter the code or comment the code out in order to figure out which bits break, as I often find this the easiest way to find out what things do. The more complex code is derived from the simpler, so you can also approach it by figuring out the simpler first. I can add some explanation if you say what you want explained but explaining it all would be too long for one answer, I think. – cfr Sep 20 '15 at 12:18
  • To get a grasp of how your code works, I've been trying to break down the simple version first. I understand most of it, but not the \IfBooleanF section. I searched for that in the TikZ/PGF manual, but didn't find that or \IfBoolean in there. Where might I go to make sense of the Boolean stuff? – WeCanLearnAnything Oct 07 '15 at 22:51
  • @WeCanLearnAnything Take a look at the documentation for xparse. The command is from there. This also covers the \NewDocumentCommand I'm using and the syntax for specifying arguments in this case. xparse provides greatly enhanced facilities for defining and redefining commands and environments, including nice ways to test whether optional arguments are supplied, if a star is used etc. Here, the \IfBoolean... is testing whether the starred form of the command is used or not. – cfr Oct 07 '15 at 23:02
  • Ok, I'll do that and probably comment here again when I have time. :) – WeCanLearnAnything Oct 07 '15 at 23:53
  • This is my take of the \IfBooleanF part. If the * is absent, then optional argument #1 is false and so nothing gets written, i.e. the entire \IfBooleanF section may as well not be there. But, if the * is present in then that makes optional argument #1 true, setting up the writing of the mixed numbers underneath. Is this correct? If it is, I'm going to try to make more sense of the actual code for the mixed numbers. – WeCanLearnAnything Oct 22 '15 at 05:28
  • Actually, I started trying to make sense of the other code anyways. :) I don't quite get the format of the \ifnum part of it all. Does it have a standard format/structure? What if you don't include the \else part? I tried to find a simple guide to it online, but couldn't find one I could understand. – WeCanLearnAnything Oct 22 '15 at 05:54
  • \IfBooleanF{#1}{\foo} would run \foo only if #1 was false i.e. in this case, if there was no star. \IfBooleanTF{#1}{\bar}{\foo} runs \bar if there's a star and \foo otherwise. This is from xparse. You can drop the \else bit of an \ifnum... but you need the \fi. So \ifnum\intbit=0\let\intbit\relax\fi doesn't have an \else. If the condition is false, nothing is done. \ifnum\fracbit=0\else ... \fi needs the \else because the ... should run only if the condition is false. Here, nothing is done if the condition is true. – cfr Oct 22 '15 at 12:22
  • That is, if there's no star, the the \IfBooleanF *is* run. If there's a star, then it might as well not be there. – cfr Oct 22 '15 at 12:25
  • Finally have free time to work on this again! Regarding \ifnum\intbit=0\let\intbit\relax\fi, I get that the purpose of the code is to not typeset the integer 0, so you get 3/4 instead of 0 3/4. I'm just guessing, though, that \let\intbit\relax means "if intbit=0, then next time \intbit is typed, pretend it's not there"? – WeCanLearnAnything Nov 08 '15 at 01:56
  • @WeCanLearnAnything \relax is just a command which successfully does nothing whatsoever. So letting \intbit to \relax means that \intbit will also do nothing successfully. It isn't quite like nothing being there because, in many cases, nothing being there would give an error. But if \relax occurs in the output, then it is like nothing being there except that it will gobble a following space as all macros do. [Note: this is my understanding of it. A TeXpert would no doubt have more/more correct things to say.] – cfr Nov 08 '15 at 02:19