3

In the following code, how can nodes (containing triangles, squares and diamonds) be defined once for each, instead of repeating their definitions in every location?

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{verbatim}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{tkz-fct}
\usepackage{gensymb}
\usetikzlibrary{arrows, arrows.meta, positioning, calc, intersections, decorations.pathreplacing, decorations.pathmorphing, decorations.markings, shapes, shapes.misc, shapes.symbols, shapes.geometric, patterns, backgrounds, trees, shadows}
\usetikzlibrary{decorations.shapes}
\begin{document}
\begin{frame}[fragile,t]
\frametitle{}
\tikzset{paintt/.style={ draw=#1, fill=#1},decorate with/.style={decorate, decoration={shape backgrounds, shape=#1, shape size=1mm}}}
\tikzset{paints/.style={ draw=#1, fill=#1},decorate with/.style={decorate, decoration={shape backgrounds, shape=#1, shape size=1mm}}}
\tikzset{paintd/.style={ draw=#1, fill=#1},decorate with/.style={decorate, decoration={shape backgrounds, shape=#1, shape size=1mm}}}
\begin{tikzpicture}[scale=.9, transform shape, paint/.style={thin, draw=#1!50!black, fill=#1!50 }]
\pgfmathsetmacro{\incrmnty}{1.}
\pgfmathsetmacro{\incrmntx}{.7}
\pgfmathsetmacro{\xlab}{1997}
\pgfmathsetmacro{\xn}{14}
\pgfmathsetmacro{\yn}{6}
\begin{scope}[xshift=0cm, yshift=0cm]
\foreach \x [evaluate=\x as \aff using int(\xlab+(1*\x))]in {0,...,\xn}{\draw [black!20!white] (\incrmntx*\x,0) node [black, xshift=0cm, yshift=-.68cm, rotate=90] {\footnotesize \aff} -- +(90:\incrmnty*\yn);}
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\foreach \y [evaluate=\y as \aff using int(\y*100)]in {0,...,\yn}{\draw [black!20!white] (10,\incrmnty*\y) node [black, right] {\aff} --+(180:\incrmntx*\xn+.2);}
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [thick](0,0) -- (\incrmntx*\xn,0);
\draw [thick](\incrmntx*\xn,0) -- (\incrmntx*\xn,\incrmnty*\yn);
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [blue!30!white, ultra thick](0,\incrmnty*2.6) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}% 97
 -- ++(\incrmntx*1,.16*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}% 98
 -- ++(\incrmntx*1,.1*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}%99
 -- ++(\incrmntx*1,.06*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}%0
 -- ++(\incrmntx*1,.16*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}%1
 -- ++(\incrmntx*1,.18*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}%2
 -- ++(\incrmntx*1,.1*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}%3
 -- ++(\incrmntx*1,.1*\incrmnty) node [regular polygon,regular polygon sides=3, paintt=blue!30!white, scale=.2]{}%4
;
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [blue!60!black, ultra thick](0,\incrmnty*3.2) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}% 97
 -- ++(\incrmntx*1,.2*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}% 98
 -- ++(\incrmntx*1,.1*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}%99
 -- ++(\incrmntx*1,.06*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}%0
 -- ++(\incrmntx*1,.18*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}%1
 -- ++(\incrmntx*1,.18*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}%2
 -- ++(\incrmntx*1,.08*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}%3
 -- ++(\incrmntx*1,.13*\incrmnty) node [regular polygon,regular polygon sides=4, paints=blue!60!black, scale=.2]{}%4
;
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [blue!80!white, ultra thick](0,\incrmnty*3.6) node [diamond, paintd=blue!80!white, scale=.2]{}% 97
 -- ++(\incrmntx*1,.2*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}% 98
 -- ++(\incrmntx*1,.1*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}%99
 -- ++(\incrmntx*1,.06*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}%0
 -- ++(\incrmntx*1,.18*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}%1
 -- ++(\incrmntx*1,.18*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}%2
 -- ++(\incrmntx*1,.08*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}%3
 -- ++(\incrmntx*1,.13*\incrmnty) node [diamond, paintd=blue!80!white, scale=.2]{}%4
;
\end{scope}
\end{tikzpicture}
\end{frame}
\end{document}

enter image description here

Hany
  • 4,709

2 Answers2

4

Here is a proposal that keeps your (very nice!) symbols but cuts down the code to the specification of what really changes: the vertical distances climbed in each step. As a bonus, the code gives the nodes unique names, which are not used here. This works by adding foreach loops that contain the set mark style that steps the node counter and inserts the node. And the repeating styles get defined as 3gon and so on.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{verbatim}
\usepackage{tikz}
\usetikzlibrary{decorations.shapes,shapes.geometric}
\newcounter{mystep}
\begin{document}
\begin{frame}[fragile,t]
\frametitle{}
\tikzset{paintt/.style={ draw=#1, fill=#1},decorate with/.style={decorate, decoration={shape backgrounds, shape=#1, shape size=1mm}}}
\tikzset{paints/.style={ draw=#1, fill=#1},decorate with/.style={decorate, decoration={shape backgrounds, shape=#1, shape size=1mm}}}
\tikzset{paintd/.style={ draw=#1, fill=#1},decorate with/.style={decorate, decoration={shape backgrounds, shape=#1, shape size=1mm}}}
\begin{tikzpicture}[scale=.9, transform shape, paint/.style={thin,
draw=#1!50!black, fill=#1!50 },set mark/.style={%
/utils/exec=\stepcounter{mystep},
insert path={node [#1] (X-\arabic{mystep}){}}},
3gon/.style={regular polygon,regular polygon sides=3, paintt=blue!30!white,scale=.2},
4gon/.style={regular polygon,regular polygon sides=4, paints=blue!60!black,scale=.2},
dia/.style={diamond, paintd=blue!80!white, scale=.2}
]
\pgfmathsetmacro{\incrmnty}{1.}
\pgfmathsetmacro{\incrmntx}{.7}
\pgfmathsetmacro{\xlab}{1997}
\pgfmathsetmacro{\xn}{14}
\pgfmathsetmacro{\yn}{6}
\begin{scope}[xshift=0cm, yshift=0cm]
\foreach \x [evaluate=\x as \aff using int(\xlab+(1*\x))]in {0,...,\xn}{\draw [black!20!white] (\incrmntx*\x,0) node [black, xshift=0cm, yshift=-.68cm, rotate=90] {\footnotesize \aff} -- +(90:\incrmnty*\yn);}
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\foreach \y [evaluate=\y as \aff using int(\y*100)]in {0,...,\yn}{\draw [black!20!white] (10,\incrmnty*\y) node [black, right] {\aff} --+(180:\incrmntx*\xn+.2);}
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [thick](0,0) -- (\incrmntx*\xn,0);
\draw [thick](\incrmntx*\xn,0) -- (\incrmntx*\xn,\incrmnty*\yn);
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [blue!30!white, ultra thick]
(0,\incrmnty*2.6) [set mark=3gon] % 97
foreach \X in {.16,.1,.06,.16,.18,.1,.1}
{ -- ++(\incrmntx*1,\X*\incrmnty) [set mark=3gon]};
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [blue!60!black, ultra thick]
(0,\incrmnty*3.2) [set mark=4gon]% 97
foreach \X in {.2,.1,.06,.18,.18,.08,.13}
{ -- ++(\incrmntx*1,\X*\incrmnty) [set mark=4gon]};
\end{scope}
\begin{scope}[xshift=0cm, yshift=0cm]
\draw [blue!80!white, ultra thick](0,\incrmnty*3.6) [set mark=dia]% 97
foreach \X in {.2,.1,.06,.18,.18,.08,.13}
{ -- ++(\incrmntx*1,\X*\incrmnty) [set mark=dia]};
\end{scope}
\end{tikzpicture}
\end{frame}
\end{document}

enter image description here

2

with pgfplots you can avoid your problem (but you need to defined data off-line):

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{verbatim}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{frame}[fragile]
\frametitle{diagram drawn by \texttt{pgfplots}}
\centering
    \begin{tikzpicture}
  \begin{axis}[
width = 0.9\linewidth, height=0.7\textheight,
grid,
 ymin = 0, ymax= 600,
ytick = {0,100,...,600},
 xmin = 1997, xmax=2011,
xtick = {1997,1998,...,2011},
xticklabel style = {rotate=90,anchor=east,
                    /pgf/number format/1000 sep={}},
   enlargelimits = false,
every axis plot post/.append style={very thick},
every mark/.append style={drawn=none, minimum size=2pt}
                ]
\addplot +[mark=diamond*]   coordinates {(1997,250) (1998,280) (1999,290)
                                        (2000,300) (2001,310) (2002,330)
                                        (2003,340) (2004,360)};;
\addplot +[mark=triangle*]  coordinates {(1997,350) (1998,380) (1999,390)
                                        (2000,400) (2001,410) (2002,430)
                                        (2003,440) (2004,460)};
\addplot +[mark size=1.6pt,
           mark=square*]    coordinates {(1997,320) (1998,350) (1999,360)
                                        (2000,370) (2001,390) (2002,400)
                                        (2003,410) (2004,430)};
  \end{axis}
\end{tikzpicture}
    \end{frame}
\end{document}

enter image description here

  • i didn't bother to define color of line. if you not like default selection, you can define own colors in \addplot option: \addplot +[<your color>, ...],
  • coordinates i estimated from provided images.
  • for more details see Manual for Package pgfplots (or ask new question on this site ;-) )
  • instead of use coordinates you can define table with data for all three coordinate sets. with this code become shorter:

    \documentclass{beamer}
    \beamertemplatenavigationsymbolsempty
    \usepackage{verbatim}
    \usepackage{pgfplots}
    \pgfplotsset{compat=1.16}
    
    \begin{document}
    \begin{frame}[fragile]
    \frametitle{diagram drawn by \texttt{pgfplots}}
    \pgfplotstableread{%
            date   y1      y2      y3
            1997   250    350    320
            1998   280    390    350
            1999   290    380    360
            2000   300    400    370
            2001   310    410    390
            2002   330    430    400
            2003   340    440    410
            2004   360    460    430
                        }\mydata
    
    \centering
        \begin{tikzpicture}
      \begin{axis}[
    width = 0.9\linewidth, height=0.7\textheight,
    grid,
     ymin = 0, ymax= 600,
    ytick = {0,100,...,600},
     xmin = 1997, xmax=2011,
    xtick = {1997,1998,...,2011},
    xticklabel style = {rotate=90,anchor=east,
                        /pgf/number format/1000 sep={}},
       enlargelimits = false,
    every axis plot post/.append style={very thick},
    every mark/.append style={drawn=none, minimum size=2pt}
                    ]
    \addplot +[mark=diamond*]   table[x=date, y=y1] {\mydata};
    \addplot +[mark=triangle*]  table[x=date, y=y2] {\mydata};
    \addplot +[mark size=1.6pt,
               mark=square*]    table[x=date, y=y3] {\mydata};
      \end{axis}
    \end{tikzpicture}
        \end{frame}
    \end{document}
    

result is the same as before.

Zarko
  • 296,517
  • @ZarkoThank you very very much for your answer. It is very comprehensive, precise and useful. I am sorry for the delay of my comment. – Hany Feb 09 '19 at 04:50