Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

My purpose is rather simple: use tikzpictures to draw tables of numbers, where the numbers are drawn inside colored boxes with fancy shapes, with different shapes and colors for different numbers. Below I boxed numbers according to whether they were odd, even, or prime (and treated 1 as a special number).

The idea is to use the colors and shapes to spot patterns. My original plan was to use this to teach prime numbers, but I have since thought of other things that could be fun to do.

As I'm new to tikz (a few days on it only), there are still some basic things that are eluding me. Here are the improvements and alterations I'd like to make on the basic table displayed below.

  1. Resize the shapes to approximately the same "size"

    There are several interpretations of what that might mean, any reasonable one will be fine. Right now, the boxes adapt to the size of the numbers, with single-digit numbers having small boxes, two-digit numbers larger boxes, and three-digit numbers even larger. I'd like the numbers to shrink rather than the boxes. You can also see that I had trouble getting the star shape to align with the other shapes. I did fool around with anchor, inner sep and outer sep, but that's all I know of at this time.

  2. Control the direction in which the numbers are running

I am asking this as a separate question, by popular demand: Tikz Nodes Order and Shapes with a General Number of Nodes

To be clear, I will be generating tables of different sizes, some with 10 numbers, some with 100 numbers, possibly more, some with longer rows, some with longer columns, and I'd like the shapes to resize automatically and proportionately.

I haven't thought through the choice of shapes and colors, it's a first pass. Feel free to beautify ;-)

This is the code so far:

\RequirePackage[svgnames,x11names]{xcolor}
\documentclass[tikz,convert=false,margin=0pt]{standalone}%
\usetikzlibrary{shapes.geometric}% polygon, ellipse, star, diamond, etc.
\usepackage{tkz-euclide}% \pgfmathisprime command
\usepackage{rotating}% sideways environment

\begin{document}%
\begin{tikzpicture}[%
  every node/.style = {
    shape = circle
    , align = center
    , scale = 2
    , anchor = base
    , font = \fontfamily{pzc}\selectfont% common font
  } ,
  % Prime Numbers
  PrimeStyle/.style = {
    regular polygon
    , regular polygon sides = 3
    , rounded corners = .5em
    , inner sep = 0pt 
    , outer sep = 0pt
    , draw = DarkGreen, thick
    , fill = green!70!black
    , text = white
  } ,
  % Even Numbers 
  EvenStyle/.style = {
    shape = circle
    , inner sep = 2pt
    , draw = DarkRed, thick
    , fill = red!70!black
    , text = white
  } ,
  % Non-Prime Odd Numbers
  OddStyle/.style = {
    shape = diamond
    , rounded corners = .5em
    , inner sep = 1pt
    , draw = DarkBlue, thick
    , fill = blue!70!black
    , text = white
  } , 
  % Number One
  OneStyle/.style = {
    shape = star
    , rounded corners = .5em
    , inner sep = 2pt
    , scale = 0.9
    , draw = white!70!black, thick
    , fill = blue!50!green!50!
    , text = black
  }
]%
%
  % Set Grid Dimensions 
  \newcommand{\xa}{1}
  \newcommand{\xb}{10}
  \newcommand{\ya}{1}
  \newcommand{\yb}{10}
  \pgfmathsetmacro{\yc}{\yb-1}% \yb minus one
% 
  % Change styles of numbers according to set membership
  \foreach \x in {\xa,...,\xb}
    \foreach \y in {\ya,...,\yb} 
       {\pgfmathtruncatemacro{\label}{\x - \xb * (\y - \yb) }
         \pgfmathparse{int(mod(\label,2))}
         \let \r \pgfmathresult
         \ifnum \r = 1
           \tikzset{EvenStyle/.style = {OddStyle}}
         \fi
         \pgfmathisprime{int(\label)}
         \let \s \pgfmathresult
         \ifnum \s = 1
           \tikzset{EvenStyle/.style = {PrimeStyle}}
         \fi
         \pgfmathparse{int(\label)}
         \let \t \pgfmathresult
         \ifnum \t = 1
           \tikzset{EvenStyle/.style = {OneStyle}}
         \fi
         \node [EvenStyle]  (\x\y) at (1.5*\x, -1.5*\y) {\label};} 
  \foreach \x in {\xa,...,\xb}
    \foreach \y [count = \yi] in {\ya,...,\yc}
      \draw (\x\y)(\x\yi) (\y\x)(\yi\x) ;
\end{tikzpicture}%
\end{document}%

% doesn't work, why?
% \foreach \k in {1,2,3,5,7,11,13}
%  \tikzset{EvenStyle/.style = {PrimeStyle}} ;

This is the immediate predecessor to this question: Looking for Elegance and Convenience in Code with Many Numbers where Harish Kumar showed me how to write general code using foreach loops.

This is where I learned of a slightly different way of defining the grid: Selecting specific nodes and changing style (for those nodes)

This is where I learned about the \pgfmathisprime command from the tikz-euler package: How to produce a list of prime numbers in LaTeX

Here I saw one of several examples where I learned how to use ifnum with int and mod and \pgfmathparse : How to use mod operation in latex with tikz

enter image description here

share|improve this question
    
You have quite a few questions in here. It would be better if you would split them into different questions which might be use to others are well. For instance, I can't think of any reason, why #1 can not be a standalone question, having nothing to do with this table. –  Peter Grill Feb 2 at 17:32
    
Thanks Peter. Yes they are distinct questions. Question 1 is my main problem right now, but I thought it would be dealt with quickly, probably some command I don't know about, so I thought I would ask Question 2 in the same breath. Question 3 was an afterthought, perhaps I should remove it altogether. The reason I'm asking Question 1 in the context of a large table is because I've had no alignment problems in much smaller tables (if you follow my first link, you'll see there 2 by 2 tables where there is no alignment issue. –  PatrickT Feb 2 at 17:37
1  
Also, it might easier to see patterns if there was a specific pattern/color that would identify each group. For example: circles for even, triangular shapes for odd, and colors for distinguishing between prime/composite. So 1 would be a triangle shape, but since it is neither prime nor composite, it could use a different color. Or any other combination of these, but there really should be an easy way to identify a group. I don't see such an obvious pattern in the above. –  Peter Grill Feb 2 at 17:39
    
Yes, I agree and that's what I did try. Unless I'm mistaken I have: red circles for even numbers, blue diamonds for non-prime odd numbers, and green triangles for prime numbers, with the number 1 having a color that is supposedly half-green and half-blue and a shape that is my best shot at being half-triangle and half-diamond. Obviously a better job can be done since you didn't see that! Oops, my bad. –  PatrickT Feb 2 at 17:53
1  
Yes, I know you had an algorithm to determine the color and pattern, but that is not something most humans can see. For instance you say you have "red circles for even numbers", yet 2 does not have a red circle. So you rule is really, "red circles for non-prime even numbers". I was just suggesting easier rules. –  Peter Grill Feb 2 at 19:13

2 Answers 2

up vote 6 down vote accepted

I'm not sure if it's answering all your questions, but I think the following (although not perfect) shows some ways in which your code could be simplified. I think there will always be some manual adjustment involved though (e.g., setting appropriate inner sep).

\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{shapes.geometric}
\begin{document}
\tikzset{%
  set color/.style={
    fill=#1,
    draw=#1!50!black
  },
  every number/.style={
    text=white,
    rounded corners=0.125cm,
    font=\fontfamily{pzc}\selectfont,
    text width=3ex,
    align=center,
    scale=2
  },
  every prime number/.style={
    shape=diamond,
    set color=blue!70!black,
    inner sep=0.25ex,
  },
  every even number/.style={
    shape=circle,
    set color=red!70!black,
    inner sep=0.5ex
  },
  every odd number/.style={
    shape=regular polygon,
    regular polygon sides=3,
    set color=green!70!black,
    inner sep=-0.375ex
  },
  number 1/.style={
    shape=star,
    set color=green!50!blue,
    inner sep=-.25ex
  }
}%
\begin{tikzpicture}[x=2cm, y=2cm]
\foreach \n [evaluate={%
    \x=mod(\n-1,10); 
    \y=floor((\n-1)/10);
    \p=isprime(\n);
    \e=mod(\n,2)==0;
    \style=(\p || \n==2) ? "prime" : (\e ? "even" : "odd");}] in {1,...,100}
  \node [every number/.try, every \style\space number/.try, number \n/.try]
     at (\x,\y) {\n};
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
    
Wow, this is superb, thanks Mark. The code is so different from mine too (which took me about 2 hours of hard toil to get to work), I didn't know about the isprime function, and the syntax is very new to me. Now I see on page 699 of the TikZ-PGF manual (v. 2.10) a list of recognized functions that includes isprime. I'll have to look into this and learn. The question mark syntax is new to me also. I can't believe how simple the code is and you manage to perfectly align and keep things in proportions. Brilliant, thanks Mark. –  PatrickT Feb 3 at 10:12
    
Oh wait, I'm getting "Package PGF Math Error: Unknown function 'isprime' ..." It's otherwise working. Do I have an obsolete version of PGF? Let me look into this... The ChangeLog reports "2010-10-25 ... Released version 2.10" which seems to be the latest version. Ah, maybe I need to load some option? Let me look into this ... –  PatrickT Feb 3 at 10:15
    
I tried to add \usetikzlibrary{calc} and wrapping things with \pgfmathparse, as suggested here tex.stackexchange.com/questions/9722/…. I also went into /usr/local/texlive/2013/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.c‌​ode.tex and sudo edited 2 instances of %\pgfmathparse{getargs(#1,#2)} to \pgfmathparse{#1,#2} even though they were explicitly commented with % For compatability with old code. but that didn't help. I'll search for more hints ... –  PatrickT Feb 3 at 12:07
    
Eureka! I followed these steps to get the development version of PGF/TikZ: tex.stackexchange.com/questions/68608/update-tikz-pgf-on-mac, with TeXLive 2013, I had to unpack in the user texmf-var directory rather than texmf –  PatrickT Feb 3 at 12:43
    
TeXLive 2013 is not all that old and I bet many people are still on TeXLive 2012, I wonder if isprime works on 2012 out of the box... –  PatrickT Feb 3 at 12:58

I have learned a lot from your answers and am very grateful. As an epilogue, I'd like to point out that in a thread I had not seen at the time I asked my question, Paul Gaborit shows how to trace a spiralling path. This is in the context of the Eratosthene sieve: I came to realize that there is a huge history of designing the kind of board I was after: the Ulam spiral, the Sacks spiral, etc.. Amazing stuff:

Sieve of Eratosthenes in tikz

I have adapted the various pieces of code generously shared by several contributors to obtain the following, posted here for the record if not for its novelty:

\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{shapes.geometric}% polygon, ellipse, star, diamond, etc.
\usetikzlibrary{shapes.symbols}% starburst, 
\usetikzlibrary{shadows}
\usetikzlibrary{shadings}
% Needs development version of PGF/TikZ
% Unpack pgf_CVS.ds.zip inside: Users/UserName/Library/texlive/2013/texmf-var

\begin{document}
% Set Grid Dimensions
\newif\ifcurrent\currenttrue
\ifcurrent
  \newcommand{\na}{0}%    first number
  \newcommand{\nb}{30}%   last number
  \newcommand{\nn}{0.5}%  tweak scale
\fi
\newcommand{\ns}{0}%  special number, irregular star shape

\tikzset{%
  set color/.style = {
    fill = #1,
    draw = #1!50!black,
  },
  every number/.style = {
    opacity = 0.9,
    drop shadow,
    inner sep = 0.25ex,
    text = white,
    font = \fontfamily{pzc}\selectfont,
    align = center,
    scale = \nn
  },
  every even number/.style = {
    set color = blue!70!black,
    shape = circle,
    inner sep = 1ex
  },
  every odd number/.style = {
    set color = blue!70!black,
    shape = diamond,
    inner sep = 1.2ex
  },
  every prime number/.style = {
    set color = red!70!black,
    shape = diamond,
    inner sep = 1.2ex,
  },
  number 2/.style = {
    set color = red!70!black,
    shape = circle,
    inner sep = 1ex
  },
  special number \ns/.style = {
    shape = starburst,
    starburst points = 7,
    drop shadow,
    set color = green!50!blue,
    inner sep = 1ex
  },
  every dot/.style ={
    set color = green!50!blue
  }
}%

\begin{tikzpicture}
  \coordinate (last);
  \foreach \n [evaluate={% 
    % \style: \p for prime, \e for even
    % x ? y : z means "if x then y else z"
    \p = isprime(\n);
    \e = mod(\n,2)==0;
    \style= \p ? "prime" : (\e ? "even" : "odd");
    % \coordinate: \r for radius, \a for angle
    \r = sqrt(\n)/2;
    \a = sqrt(\n)*360;
    }] in {\na,...,\nb}{%
  \coordinate(new) at (\a:\r);
  \draw[every dot/.try] (last) to[bend right={6/sqrt(\n)}] (new);
  \node[every number/.try, every \style\space number/.try, number \n/.try,
    special number \n/.try, minimum size=1cm](last) at (\a:\r) {\n};
  }%
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
Oops! the number 2 should be red (prime), must fix this... –  PatrickT Feb 4 at 13:13
    
fixed! I didn't find a straightforward way to do it, in finite time, so I just added a separate style for the number 2, the only even prime number (in my previous code it was incorrectly in blue color like any vulgar even number). –  PatrickT Feb 4 at 23:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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