58

I can't find much information about creating TikZ fill patterns or even using the custom built-in patterns. Look to do all the common fills like lines, hatches, dots, stars, etc... I need to be able to control the scale, too. (The patterns I did end up finding were way to large.)

Google doesn't seem to return much info on TikZ fill patterns.

7
  • 2
    Refer chapter 41 of pgf manual on patterns.
    – user11232
    May 4, 2012 at 8:44
  • @HarishKumar This gives some(or all?) built in patterns but doesn't describe how to change the scale or create built in ones?
    – Uiy
    May 4, 2012 at 9:43
  • you may have to look in to the source code of pattern library.
    – user11232
    May 4, 2012 at 10:11
  • Refer also to chapter 62 (pgf2.00) or chapter 78 (pgf2.10) to define custom patterns.
    – guillem
    May 4, 2012 at 10:23
  • possible duplicate of Hatch a rectangle in TikZ
    – lockstep
    May 6, 2012 at 8:59

2 Answers 2

81

Customizing an existing pattern

The fivepointed star pattern is defined in pgflibrarypatterns.code.tex as

\pgfdeclarepatternformonly{fivepointed stars}% name
  {\pgfpointorigin}% bottom left
  {\pgfqpoint{3mm}{3mm}}% top right
  {\pgfqpoint{3mm}{3mm}}% tile size
  {% code
   \pgftransformshift{\pgfqpoint{1mm}{1mm}}
   \pgfpathmoveto{\pgfqpointpolar{18}{1mm}}
   \pgfpathlineto{\pgfqpointpolar{162}{1mm}}
   \pgfpathlineto{\pgfqpointpolar{306}{1mm}}
   \pgfpathlineto{\pgfqpointpolar{90}{1mm}}
   \pgfpathlineto{\pgfqpointpolar{234}{1mm}}
   \pgfpathclose%
   \pgfusepath{fill}
  }

If you want to change the size of stars or how far away they are of each other, you just need to change the 1mm and 3mm values respectively, but you need to define a new pattern for that. If you want full flexibility, you need to define a pattern with variables which you can adjust. Let's say we want the starsize and starspread parameters to customize the pattern. We first define the lengths:

% defining the new dimensions
\newlength{\starsize}
\newlength{\starspread}

then declare the corresponding tikz keys:

% declaring the keys in tikz
\tikzset{starsize/.code={\setlength{\starsize}{#1}},
         starspread/.code={\setlength{\starspread}{#1}}}

then set the default values:

% setting the default values
\tikzset{starsize=1mm,
         starspread=3mm}

and finally declare the pattern itself using our variables:

% declaring the pattern
\pgfdeclarepatternformonly[\starspread,\starsize]% variables
  {custom fivepointed stars}% name
  {\pgfpointorigin}% lower left corner
  {\pgfqpoint{\starspread}{\starspread}}% upper right corner
  {\pgfqpoint{\starspread}{\starspread}}% tilesize
  {% shape description
   \pgftransformshift{\pgfqpoint{\starsize}{\starsize}}
   \pgfpathmoveto{\pgfqpointpolar{18}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{162}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{306}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{90}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{234}{\starsize}}
   \pgfpathclose%
   \pgfusepath{fill}
  }

You can then just use things like \draw[pattern=custom fivepointed stars,starspread=1.5mm,starsize=0.5mm] (0,0) rectangle (3,4); to produce small stars close to each other in a rectangle. Here's the full code:

tikz star patterns examples

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{patterns}

% defining the new dimensions
\newlength{\starsize}
\newlength{\starspread}
% declaring the keys in tikz
\tikzset{starsize/.code={\setlength{\starsize}{#1}},
         starspread/.code={\setlength{\starspread}{#1}}}
% setting the default values
\tikzset{starsize=1mm,
         starspread=3mm}
% declaring the pattern
\pgfdeclarepatternformonly[\starspread,\starsize]% variables
  {custom fivepointed stars}% name
  {\pgfpointorigin}% lower left corner
  {\pgfqpoint{\starspread}{\starspread}}% upper right corner
  {\pgfqpoint{\starspread}{\starspread}}% tilesize
  {% shape description
   \pgftransformshift{\pgfqpoint{\starsize}{\starsize}}
   \pgfpathmoveto{\pgfqpointpolar{18}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{162}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{306}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{90}{\starsize}}
   \pgfpathlineto{\pgfqpointpolar{234}{\starsize}}
   \pgfpathclose%
   \pgfusepath{fill}
  }

\begin{document}

\begin{center}
%
\begin{tikzpicture}
\draw[pattern=fivepointed stars] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\begin{tikzpicture}
\draw[pattern=custom fivepointed stars,starspread=5mm] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\begin{tikzpicture}
\draw[pattern=custom fivepointed stars,starspread=5mm,starsize=2mm] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\begin{tikzpicture}
\draw[pattern=custom fivepointed stars,starspread=1.5mm,starsize=0.5mm] (0,0) rectangle (3,4);
\end{tikzpicture}
%
\end{center}

\end{document}

In the same vein, you can customize hatch lines. Here's the code for north west lines. I've put options for color and shifting the hatch lines up (not down):

tikz hatch pattern which can be colored

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{patterns}

% defining the new dimensions and parameters
\newlength{\hatchspread}
\newlength{\hatchthickness}
\newlength{\hatchshift}
\newcommand{\hatchcolor}{}
% declaring the keys in tikz
\tikzset{hatchspread/.code={\setlength{\hatchspread}{#1}},
         hatchthickness/.code={\setlength{\hatchthickness}{#1}},
         hatchshift/.code={\setlength{\hatchshift}{#1}},% must be >= 0
         hatchcolor/.code={\renewcommand{\hatchcolor}{#1}}}
% setting the default values
\tikzset{hatchspread=3pt,
         hatchthickness=0.4pt,
         hatchshift=0pt,% must be >= 0
         hatchcolor=black}
% declaring the pattern
\pgfdeclarepatternformonly[\hatchspread,\hatchthickness,\hatchshift,\hatchcolor]% variables
   {custom north west lines}% name
   {\pgfqpoint{\dimexpr-2\hatchthickness}{\dimexpr-2\hatchthickness}}% lower left corner
   {\pgfqpoint{\dimexpr\hatchspread+2\hatchthickness}{\dimexpr\hatchspread+2\hatchthickness}}% upper right corner
   {\pgfqpoint{\dimexpr\hatchspread}{\dimexpr\hatchspread}}% tile size
   {% shape description
    \pgfsetlinewidth{\hatchthickness}
    \pgfpathmoveto{\pgfqpoint{0pt}{\dimexpr\hatchspread+\hatchshift}}
    \pgfpathlineto{\pgfqpoint{\dimexpr\hatchspread+0.15pt+\hatchshift}{-0.15pt}}
    \ifdim \hatchshift > 0pt
      \pgfpathmoveto{\pgfqpoint{0pt}{\hatchshift}}
      \pgfpathlineto{\pgfqpoint{\dimexpr0.15pt+\hatchshift}{-0.15pt}}
    \fi
    \pgfsetstrokecolor{\hatchcolor}
%    \pgfsetdash{{1pt}{1pt}}{0pt}% dashing cannot work correctly in all situation this way
    \pgfusepath{stroke}
   }

\begin{document}

\begin{center}
%
\begin{tikzpicture}
\draw[pattern=custom north west lines] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\begin{tikzpicture}
\draw[pattern=custom north west lines,hatchspread=6pt,hatchthickness=1pt,hatchcolor=red] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\begin{tikzpicture}
\draw[pattern=custom north west lines,hatchspread=10pt,hatchthickness=5pt] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\begin{tikzpicture}% hatchshift must be >= 0
\draw[pattern=custom north west lines,hatchspread=10pt,hatchcolor=red] (0,0) rectangle (3,4);
\draw[pattern=custom north west lines,hatchspread=10pt,hatchcolor=blue,hatchshift=2.5pt] (0,0) rectangle (3,4);
\draw[pattern=custom north west lines,hatchspread=10pt,hatchcolor=green!65!black,hatchshift=5pt] (0,0) rectangle (3,4);
\draw[pattern=custom north west lines,hatchspread=10pt,hatchcolor=violet,hatchshift=7.5pt] (0,0) rectangle (3,4);
\end{tikzpicture}%
%
\end{center}

\end{document}

Here's the code for north east lines:

\pgfdeclarepatternformonly[\hatchspread,\hatchthickness,\hatchshift,\hatchcolor]% variables
   {custom north east lines}% name
   {\pgfqpoint{\dimexpr-2\hatchthickness}{\dimexpr-2\hatchthickness}}% lower left corner
   {\pgfqpoint{\dimexpr\hatchspread+2\hatchthickness}{\dimexpr\hatchspread+2\hatchthickness}}% upper right corner
   {\pgfqpoint{\dimexpr\hatchspread}{\dimexpr\hatchspread}}% tile size
   {% shape description
    \pgfsetlinewidth{\hatchthickness}
    \pgfpathmoveto{\pgfqpoint{\dimexpr\hatchshift-0.15pt}{-0.15pt}}
    \pgfpathlineto{\pgfqpoint{\dimexpr\hatchspread+0.15pt}{\dimexpr\hatchspread-\hatchshift+0.15pt}}
    \ifdim \hatchshift > 0pt
      \pgfpathmoveto{\pgfqpoint{-0.15pt}{\dimexpr\hatchspread-\hatchshift-0.15pt}}
      \pgfpathlineto{\pgfqpoint{\dimexpr\hatchshift+0.15pt}{\dimexpr\hatchspread+0.15pt}}
    \fi
    \pgfsetstrokecolor{\hatchcolor}
%    \pgfsetdash{{1pt}{1pt}}{0pt}% dashing cannot work correctly in all situation this way
    \pgfusepath{stroke}
   }

Creating new patterns

Creating new patterns is a bit more complex and needs choosing the right shape, the bounding box overlapping, etc. You can see an example with hexagons in the question Drawing Hexagons. I didn't do the work to control the size within Tikz, but it's straightforward to adapt the method described above.

9
  • Philippe, nice answer. I was wondering, can you change the color of the lines or their style (dashed, dotted, etc)? And another thing, what if you put two of these slightly overlapping each other, how do you make sure both lines/colors are easily visible? If you just overlap them as they are, the second one covers the first one. I tried a yshift but it doesn't work well. :P
    – Alenanno
    Apr 5, 2013 at 15:02
  • 2
    @Alenanno: I've added options for the color and the shifting. Dotted or dashed lines won't work correctly because of how the patterns are made. Apr 7, 2013 at 6:47
  • @PhilippeGoutet Brilliant, thanks. Yeah, well I've noticed... are the lines made of many shorter lines in sequence? Is that the reason?
    – Alenanno
    Apr 7, 2013 at 8:39
  • @Alenanno: Yes, that's the reason. If you really want dashed hatching, you could clip to your shape some lines made with a for loop, but it's a bit cumbersome. Apr 7, 2013 at 10:01
  • 1
    Very good answer. Though for the color I would rather use the existing key pattern color, which can be used in the pattern with \tikz@pattern@color. You additionally need \makeatletter and \makeatother. Beware: Do not forget to add \tikz@pattern@color in the list of variables. See also this answer for an example.
    – John
    Sep 13, 2018 at 7:54
0

I tried to use the answer from Philippe Goutet to create a custom pattern in pgfgantt bars. However, the hatching was off and did not align with the bar borders very well. I ended up using the mylines example from http://mirror.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf#page=737 which worked great. You can easily customize the hatching's spacing, line width and angle.

\documentclass{standalone}

\PassOptionsToPackage{usenames,dvipsnames}{xcolor}
\usepackage{tikz}
\usepackage{pgfgantt}

\usetikzlibrary {patterns.meta}
\tikzdeclarepattern{
  name=mylines,
  parameters={
      \pgfkeysvalueof{/pgf/pattern keys/size},
      \pgfkeysvalueof{/pgf/pattern keys/angle},
      \pgfkeysvalueof{/pgf/pattern keys/line width},
  },
  bounding box={
    (0,-0.5*\pgfkeysvalueof{/pgf/pattern keys/line width}) and
    (\pgfkeysvalueof{/pgf/pattern keys/size},
     0.5*\pgfkeysvalueof{/pgf/pattern keys/line width})},
  tile size={(\pgfkeysvalueof{/pgf/pattern keys/size},
              \pgfkeysvalueof{/pgf/pattern keys/size})},
  tile transformation={rotate=\pgfkeysvalueof{/pgf/pattern keys/angle}},
  defaults={
    size/.initial=5pt,
    angle/.initial=45,
    line width/.initial=.4pt,
}, code={
\draw [line width=\pgfkeysvalueof{/pgf/pattern keys/line width}] (0,0) -- (\pgfkeysvalueof{/pgf/pattern keys/size},0);
}, }

\begin{document}

\begin{ganttchart}{1}{12}
    \gantttitle{2022}{12} \\
    \gantttitlelist{1,...,12}{1} \\
    \ganttbar[bar/.append style={preaction={fill, LimeGreen},pattern={mylines[size=5pt,line width=2.5pt,angle=45]},pattern color=NavyBlue}]{Work Package 1}{1}{12}
\end{ganttchart}

\end{document}

pgfgantt

1
  • 1
    Welcome to TeX.SE!
    – Mensch
    Nov 8, 2021 at 18:23

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.