16

Problem

I would like to indicate an infeasible region in one of my pgfplots by manually drawing a path in the canvas. This should be a hatched pattern that is decorated on the path, something like north east lines from \usepgflibrary{patterns}.

MWE

\documentclass{standalone}

\usepackage{pgfplots} \pgfplotsset{compat=1.10}

\begin{document}

\begin{tikzpicture} \begin{axis}[ % axis equal image, xlabel = {$x$}, ylabel = {$y$}, grid, xmin = 0, xmax = 3000, ymin=400, xmax = 2200, width=0.5\textwidth, every node near coord/.append style={font=\tiny\scshape}, nodes near coords align={vertical}, ] \addplot+[only marks, nodes near coords, point meta=explicit symbolic] table[meta=label] { x y label 2500 1500 a 1306 1655 b 200 1000 c 1600 1570 d 1500 2000 e }; % path to be decorated \draw (axis cs:1000, 500) -- (axis cs:2750,500) -- (axis cs:2750, 2000) -- (axis cs: 1000, 2000) -- cycle; \end{axis} \end{tikzpicture}

\end{document}

Challenges

Unfortunately I have no idea how to approach this. Can you help out?

Here are some challenges:

  • Maybe this can be done by decorating the path, but I don't know how this works.

  • It is important that the pattern is bounded by the actual path and "bulges outwards". The pattern must not replace the path, but be "on the edge". Bonus: to indicate inverse problems, the pattern could also "bulge inwards".

  • north east lines sometimes looks better than north west lines, based on the orientation. Can this choice be automated?

Illustration

By "bulging outwards", I mean the following:

Bulging outwards

"Inwards" would be the inverse:

Bulging inwards

I apologize for this sacrilege of a drawing. Because it looks terrible we need Tikz!

Ingo
  • 20,035
  • Could you explain what you mean by "bulges outwards"? Maybe include a sketch of the desired result. – Jake Jul 09 '14 at 14:31
  • I have added an illustration! – Ingo Jul 09 '14 at 14:57
  • 1
    Ahh, yes, thanks for the illustration, that helps. I thought the whole area should be hatched. You might find some inspiration for a solution at Drawing Mechanical Systems in LaTeX. – Jake Jul 09 '14 at 15:01
  • For a solution which can accommodate arbitrary closed shapes, see https://tex.stackexchange.com/questions/419533/tikz-how-to-draw-a-pattern-at-the-border-of-a-tikz-path/ – user1476176 Jun 05 '23 at 19:04
  • There is also a solution which can accommodate open closed or open shapes at https://tex.stackexchange.com/questions/518580/tikz-how-to-draw-a-pattern-at-the-border-of-a-not-closed-tikz-path – user1476176 Jun 08 '23 at 14:20

2 Answers2

15

Another possible solution is the use of clip techniques and patterns from tikzlibrary.

Addendum:

To make them automatic, one can define a macro with two arguments,say, #1=lines pattern, #2=color. Same ideas apply to inwards macro.

\newcommand\outwards[2]{
\begin{scope}
\draw (axis cs:1000, 500) -- (axis cs:2750,500) -- (axis cs:2750, 2000) -- (axis cs: 1000, 2000) -- cycle;
\clip (axis cs:900, 450) rectangle (axis cs:2850, 2050);
\path[pattern=#1, pattern color=#2,]  (axis cs:900, 450) rectangle (axis cs:2850, 2050);
\fill[white] (axis cs:1000, 500) rectangle (axis cs:2750, 2000);
\end{scope}
}

Then call

\outwards{north west lines}{red}

enter image description here

Code

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{patterns}
\begin{document}

\begin{tikzpicture}
    \begin{axis}[
        % axis equal image,
        xlabel = {$x$},
        ylabel = {$y$},
        grid,
        xmin = 0, xmax = 3000,
        ymin=400, xmax = 2200,
        width=0.5\textwidth,
        every node near coord/.append style = {font=\tiny\scshape},
        nodes near coords align={vertical}, 
        enlarge x limits={rel=0.5, upper}
        ]


% --- code for bulging outwards

\begin{scope}
\draw (axis cs:1000, 500) -- (axis cs:2750,500) -- (axis cs:2750, 2000) -- (axis cs: 1000, 2000) -- cycle;
\clip (axis cs:900, 450) rectangle (axis cs:2850, 2050);
\path[pattern=north west lines, pattern color=red,]  (axis cs:900, 450) rectangle (axis cs:2850, 2050);
\fill[white] (axis cs:1000, 500) rectangle (axis cs:2750, 2000);
\end{scope}

% --- code for bulging inwards

\begin{scope}
\clip (axis cs:1000, 500) rectangle (axis cs:2750, 2000);
\path[pattern=north east lines,pattern color=green,]  (axis cs:1000, 500) rectangle (axis cs:2750, 2000);
\fill[white] (axis cs:1100, 560) rectangle (axis cs:2650, 1940);
\end{scope}

\addplot+[only marks, nodes near coords, point meta=explicit symbolic]
        table[meta=label] {
            x    y    label
            2500 1500 a
            1306 1655 b
             200 1000 c
            1600 1570 d
            1500 2000 e
        };
% path to be decorated
\draw (axis cs:1000, 500) -- (axis cs:2750,500) -- (axis cs:2750, 2000) -- (axis cs: 1000, 2000) -- cycle;
\draw[gray!50!white] (axis cs:1000, 1000) -- (axis cs:2750, 1000);
\draw[gray!50!white] (axis cs:1000, 1500) -- (axis cs:2750, 1500);
\draw[gray!50!white] (axis cs:2000, 500) -- (axis cs:2000, 2000);
\end{axis}
\end{tikzpicture}

\end{document}
Jesse
  • 29,686
10

It's not hard to use TikZ decorations for this:

\documentclass{standalone}
\usepackage{pgfplots}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        % axis equal image,
        xlabel = {$x$},
        ylabel = {$y$},
        grid,
        xmin = 0, xmax = 3000,
        ymin=400, ymax = 2200,
        width=0.5\textwidth,
        every node near coord/.append style={font=\tiny\scshape},
        nodes near coords align={vertical},
        ]
        \addplot+[only marks, nodes near coords, point meta=explicit symbolic]
        table[meta=label] {
            x    y    label
            2500 1500 a
            1306 1655 b
             200 1000 c
            1600 1570 d
            1500 2000 e
        };
        % path to be decorated
        \draw[
            decoration={border,segment length=1mm,amplitude=5mm,angle=-135},
            postaction={decorate,draw}
        ]  (axis cs:1000, 500) -- (axis cs:2750,500) -- (axis cs:2750, 2000)
        -- (axis cs: 1000, 2000) -- cycle;
    \end{axis}
\end{tikzpicture}
\end{document}

sample code output

For the inverse problem use a positive angle so the lines point inwards.

Matthew Leingang
  • 44,937
  • 14
  • 131
  • 195