9

I made a course schedule using TikZ, but my code is inelegant and inefficient. Most of the steps are repeated for each course, so I would like to see how to combine them. I would also like to make the code easier to modify, e.g., adding new courses, changing the times of courses, and changing the times that are displayed on the schedule. I would greatly appreciate any advice on improving it.

\documentclass[12pt]{article}
\usepackage[margin=1.25in]{geometry}
\usepackage{comment}
\pagenumbering{gobble}

\usepackage[dvipsnames]{xcolor}
\definecolor{Pantone113U}{RGB}{255 225 94}
\definecolor{Pantone2347U}{RGB}{231 69 54}
\definecolor{gPurple}{RGB}{117 102 160}
\definecolor{gEvergreen}{RGB}{0 78 66}

\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri,calc}

\begin{document}
        
        {\centering\LARGE\textbf{Fall 2020 Schedule}\\}
        \vspace{0.5in}
                
                \begin{figure}[h]
                    \centering
                    \begin{tikzpicture}
                    \draw[gray] (0,0)   -- ++(5in,0)    -- ++(0,-15cm) -- ++(-5in,0) -- cycle;
                    \draw[gray] (5in, 0) -- (0, 0)
                        node[left,black]{12 p.m.};
                    \foreach \x in {1, ..., 10}
                        \draw[gray] (5in, -1.5*\x) -- (0, -1.5*\x) node[left,black]{\x \space p.m.};
                    
                    \draw[gray] (0,0) -- (1in,0) node[midway,above,black]{Monday} -- (1in, -15cm);
                    \draw[gray] (1in,0) -- (2in,0) node[midway,above,black]{Tuesday} -- (2in,-15cm);
                    \draw[gray] (2in,0) -- (3in,0) node[midway,above,black]{Wednesday} -- (3in, -15cm);
                    \draw[gray] (3in,0) -- (4in,0) node[midway,above,black]{Thursday} -- (4in, -15cm);
                    \draw[gray] (4in,0) -- (5in,0) node[midway,above,black]{Friday} -- (5 in, -15cm);
                    
                    \path let % Course 1 on Mon
                        \p1 = (0,-1.5),
                        \p2 = (1in,-1.5),
                        \p3 = (0,{-1.5*(2+20/60)}),
                        \p4 = (1in,{-1.5*(2+20/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=gPurple!20, draw=gPurple, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 1}};
                    
                    \path let % Course 1 on Wed
                        \p1 = (2in,-1.5),
                        \p2 = (3in,-1.5),
                        \p3 = (2in,{-1.5*(2+20/60)}),
                        \p4 = (3in,{-1.5*(2+20/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=gPurple!20, draw=gPurple, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 1}};
                    
                    \path let % Course 1 on Fri
                        \p1 = (4in,-1.5),
                        \p2 = (5in,-1.5),
                        \p3 = (4in,{-1.5*(2+20/60)}),
                        \p4 = (5in,{-1.5*(2+20/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=gPurple!20, draw=gPurple, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 1}};
                    
                    
                    
                    \path let % Course 2 on Mon
                        \p1 = (0,-1.5*3),
                        \p2 = (1in,-1.5*3),
                        \p3 = (0,{-1.5*(3+50/60)}),
                        \p4 = (1in,{-1.5*(3+50/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=Pantone2347U!30, draw=Pantone2347U!80, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 2}};
                    
                    \path let % Course 2 on Wed
                        \p1 = (2in,-1.5*3),
                        \p2 = (3in,-1.5*3),
                        \p3 = (2in,{-1.5*(3+50/60)}),
                        \p4 = (3in,{-1.5*(3+50/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=Pantone2347U!30, draw=Pantone2347U!80, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 2}};
                    
                    \path let % Course 2 on Fri
                        \p1 = (4in,-1.5*3),
                        \p2 = (5in,-1.5*3),
                        \p3 = (4in,{-1.5*(3+50/60)}),
                        \p4 = (5in,{-1.5*(3+50/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=Pantone2347U!30, draw=Pantone2347U!80, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 2}};
                        
                        
                        
                    \path let % Course 3 on Mon
                        \p1 = (0,-1.5*7),
                        \p2 = (1in,-1.5*7),
                        \p3 = (0,{-1.5*(9+50/60)}),
                        \p4 = (1in,{-1.5*(9+50/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=Pantone113U!20, draw=Pantone113U, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 3}};
                        
                        
                        
                    \path let % Course 4 on Tue
                        \p1 = (1in,-1.5*2),
                        \p2 = (2in,-1.5*2),
                        \p3 = (1in,{-1.5*(3+50/60)}),
                        \p4 = (2in,{-1.5*(3+50/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=gEvergreen!20, draw=gEvergreen, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 4}};
                        
                    \path let % Course 4 on Fri
                        \p1 = (3in,-1.5*2),
                        \p2 = (4in,-1.5*2),
                        \p3 = (3in,{-1.5*(3+50/60)}),
                        \p4 = (4in,{-1.5*(3+50/60)}), in
                        coordinate (p1) at (\p1)
                        coordinate (p2) at (\p2)
                        coordinate (p3) at (\p3)
                        coordinate (p4) at (\p4)
                        coordinate (p5) at ($(\p1) !.5! (\p4)$);
                        \path[preaction={clip,postaction={fill=gEvergreen!20, draw=gEvergreen, line width=2pt}}] (p1) -- (p2) -- (p4) -- (p3) -- cycle;
                        \node at (p5) {\textbf{Course 4}};
                    \end{tikzpicture}
                \end{figure}
            
\end{document}

schedule

2

1 Answer 1

14

Here is a proposal. Install your own coordinate system with certain lengths of the x (hscale) and y (vscale) unit vector, respectively. Implement "symbolic" coordinates Mon, Tue etc. such that Mon=0 and so on. Now you can use the coordinates to refer to positions in the time table. Then define a style that makes scheduling either. (I use the 24h times since you may want to create a schedule that starts before noon.) For instance,

\node[course color=Pantone113U,course=Mon from 19 to 22]{Course 3};

will schedule a course on Monday from 7pm to 10pm with the color Pantone113U and name of the course Course 3. For courses that repeat on different days you can use foreach. The whole course schedule of your example is then achieved with

 \path 
  foreach \X in {Mon,Wed,Fri} 
  {node[course={\X} from 13 to 14.25]{Course 1}
  node[course color=Pantone2347U,course={\X} from 15 to 16]{Course 2}}
  node[course color=Pantone113U,course=Mon from 19 to 22]{Course 3}
  foreach \X in {Tue,Thu}
  {node[course color=gEvergreen,course={\X} from 14 to 15]{Course 4}} ;

Full code and result:

\documentclass[tikz,border=3mm]{standalone}
\definecolor{Pantone113U}{RGB}{255 225 94}
\definecolor{Pantone2347U}{RGB}{231 69 54}
\definecolor{gPurple}{RGB}{117 102 160}
\definecolor{gEvergreen}{RGB}{0 78 66}
\begin{document}
\begin{tikzpicture}[font=\sffamily,
    declare function={Mon=0;Tue=1;Wed=2;Thu=3;Fri=4;
    hscale=2.5;vscale=1.2;tmin=12;tmax=22;},
    yscale=-1,x=hscale*1cm,y=vscale*1cm,
    course color/.code={\colorlet{coursecolor}{#1}},
    course color=gPurple,
    course/.style args={#1 from #2 to #3}{%
            draw=coursecolor,fill=coursecolor!20,
            at={(#1,#2)},align=center,
            node font=\bfseries,
            anchor=north west,outer sep=0pt,
            minimum width=hscale*1cm,
            minimum height={abs(#3-#2)*vscale*1cm}}]
 \pgfmathtruncatemacro{\tmin}{tmin}%
 \pgfmathtruncatemacro{\tnext}{tmin+1}%
 \pgfmathtruncatemacro{\tmax}{tmax} 
 \draw[xstep=hscale*1cm,ystep=vscale*1cm]  (0,tmin) grid (5,tmax);
 \path foreach \X  [count=\Y] in
    {Monday,Tuesday,Wednesday,Thursday,Friday}
    {(\Y-0.5,12) node[above,text depth=0.25ex]{\X} }
     foreach \X [parse=true] in {\tmin,\tnext,...,\tmax}
    {(0,\X) node[left]{\ifnum\X<12\relax
     \X\ a.m.%
    \else
     \ifnum\X=12\relax
      12\ p.m.%
     \else
      \the\numexpr\X-12\relax\ p.m.%
     \fi
    \fi} }; 
 \path 
  foreach \X in {Mon,Wed,Fri} 
  {node[course={\X} from 13 to 14.25]{Course 1}
  node[course color=Pantone2347U,course={\X} from 15 to 16]{Course 2}}
  node[course color=Pantone113U,course=Mon from 19 to 22]{Course 3}
  foreach \X in {Tue,Thu}
  {node[course color=gEvergreen,course={\X} from 14 to 15]{Course 4}} ;
\end{tikzpicture}
\end{document}

enter image description here

3
  • Nice, I guess I have to blog about this. Commented Jun 15, 2020 at 5:11
  • Thank you! This is very helpful.
    – bclzyjhr
    Commented Jun 20, 2020 at 3:03
  • Do you think it is possible to insert events side-by-side if they are on the same time?
    – Sigur
    Commented Oct 27, 2022 at 23:49

You must log in to answer this question.

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