35

Everyone, I would like to draw the region

\begin{align*}
  x_1 + x_2 &\ge 3 \\
  2x_1 - x_2 &\le 5 \\
  -x_1 + 2x_2 &\le 3
\end{align*}

Here is my code to draw the region of inequality:

\documentclass{article}

\usepackage{pgfplots}
\usetikzlibrary{patterns}

\begin{document}
  \begin{figure}[htpb]
    \centering
    \label{fig:p3:c1}
    \begin{tikzpicture}
      \begin{axis}[axis on top,smooth,
        axis line style=very thick,
        axis x line=bottom,
        axis y line=left,
        ymin=-1,ymax=6,xmin=-1,xmax=6,
        xlabel=$x_1$, ylabel=$x_2$,grid=major
      ]
        \addplot[thick,pattern=crosshatch,pattern color=blue!30!white,
          domain=-10:4]{3-x} -| (axis cs:50, 50);
        \addplot[thick,pattern=crosshatch dots,pattern color=green!60!white,
          domain=-10:12]{-5+2*x} -| (axis cs: -50,50);
        \addplot[thick,pattern=grid,pattern color=yellow,
          domain=-10:10]{3/2+x/2} -| (axis cs: 20,0);
        \addplot[very thick, domain=-10:10]{3-x};
        \addplot[very thick, domain=-10:10]{-5+2*x};
        \addplot[very thick, domain=-10:10]{3/2+x/2};
      \end{axis}
    \end{tikzpicture}
    \caption{Problem 4, Part A}
  \end{figure}

\end{document}

This code have several problems.

  1. In order not let pattern to cover the line, I draw every function twice. Can we draw the pattern just before draw all the line?

  2. The grid overlap show before the line. (I also want to let axis on the top)

  3. How to fill the region above/under a curve/line? As you can see, I just use a very ugly way. It will draw unnecessary line (now it is overlapped with axis) and it is not beautiful. I need to modify the coordinate every time I change other things. Any better method?

David Carlisle
  • 757,742

5 Answers5

32

I would not do this with pgfplots but with TikZ instead:

Code

\documentclass[tikz,border=5mm]{standalone}

\begin{document}

\begin{tikzpicture}

    \draw[gray!50, thin, step=0.5] (-1,-3) grid (5,4);
    \draw[very thick,->] (-1,0) -- (5.2,0) node[right] {$x_1$};
    \draw[very thick,->] (0,-3) -- (0,4.2) node[above] {$x_2$};

    \foreach \x in {-1,...,5} \draw (\x,0.05) -- (\x,-0.05) node[below] {\tiny\x};
    \foreach \y in {-3,...,4} \draw (-0.05,\y) -- (0.05,\y) node[right] {\tiny\y};

    \fill[blue!50!cyan,opacity=0.3] (8/3,1/3) -- (1,2) -- (13/3,11/3) -- cycle;

    \draw (-1,4) -- node[below,sloped] {\tiny$x_1+x_2\geq3$} (5,-2);
    \draw (1,-3) -- (3,1) -- node[below left,sloped] {\tiny$2x_1-x_2\leq5$} (4.5,4);
    \draw (-1,1) -- node[above,sloped] {\tiny$-x_1+2x_2\leq3$} (5,4);

\end{tikzpicture}

\end{document}

Output

enter image description here

Tom Bombadil
  • 40,123
  • +1. How does one insert this picture in an article? – Américo Tavares Oct 09 '12 at 12:10
  • 3
    Just put it in the text, possibly in a figure environment: text text \begin{figure}\begin{tikzpicture} <draw commands> \end{tikzpicture}\caption{Inequalities}\end{figure} text text – Tom Bombadil Oct 09 '12 at 12:25
  • I was unable to get what I wanted because the figure without caption was inserted in a separated page. – Américo Tavares Oct 09 '12 at 12:55
  • 1
    You have to use a different documentclass (e.g. scrartcl), as standalone is just for single pictures. – Tom Bombadil Oct 09 '12 at 13:30
  • Thanks! Finally I've managed with \documentclass{article} \usepackage{tikz} ... \begin{center} ... \end{center} – Américo Tavares Oct 09 '12 at 14:35
  • I could not do what you doing. I have an article for documentclass but I cannot call this graph tex file into my original tex file. – ARAT Sep 29 '15 at 21:49
  • @TomBombadil. Could you please add comments to your codes line by line for people like us who are new to graphing with Latex? I would appreciate it a lot. – holala Oct 01 '20 at 19:31
16

1) I don't know if there is any way to draw the lines just once (except to use draw=none the first time)

2) The solution in the following code comes from tikz/pgfplots advanced z-order axis/grid.

3) Each area covers at most three vertices of the axis box, depending on the inequality sign, so you can address them via the rel axis cs syntax. You can define a new command once for all.

\documentclass{article} 

\usepackage{pgfplots} 
\usetikzlibrary{patterns}

\makeatletter
\newcommand{\pgfplotsdrawaxis}{\pgfplots@draw@axis}
\makeatother
\pgfplotsset{only axis on top/.style={axis on top=false, after end axis/.code={
             \pgfplotsset{axis line style=opaque, ticklabel style=opaque, tick style=opaque,
                          grid=none}\pgfplotsdrawaxis}}}

\newcommand{\drawge}{-- (rel axis cs:1,0) -- (rel axis cs:1,1) -- (rel axis cs:0,1) \closedcycle}
\newcommand{\drawle}{-- (rel axis cs:1,1) -- (rel axis cs:1,0) -- (rel axis cs:0,0) \closedcycle}

\begin{document} 
  \begin{figure}[htpb] 
    \centering 
    \label{fig:p3:c1} 
    \begin{tikzpicture} 
      \begin{axis}[only axis on top,
        axis line style=very thick, 
        axis x line=bottom, 
        axis y line=left, 
         ymin=-1,ymax=5.99,xmin=-1,xmax=5.99, 
         xlabel=$x_1$, ylabel=$x_2$,grid=major 
      ] 
        \addplot [draw=none, pattern=vertical lines, pattern color=blue!40, domain=-10:4]
                 {3-x} \drawge; 
        \addplot [draw=none, pattern=north west lines, pattern color=blue!40, domain=-10:12]
                 {-5+2*x} \drawge;
        \addplot [draw=none, pattern=horizontal lines, pattern color=blue!40, domain=-10:10]
                 {3/2+x/2} \drawle; 
        \addplot[very thick, domain=-10:10] {3-x}; 
        \addplot[very thick, domain=-10:10] {-5+2*x}; 
        \addplot[very thick, domain=-10:10] {3/2+x/2}; 
      \end{axis} 
    \end{tikzpicture} 
    \caption{Problem 4, Part A} 
  \end{figure} 

\end{document}

enter image description here

Luigi
  • 6,325
  • The question is old but... how would you modify the code to consider the case of a vertical line (for example, $x_1 \geq 2$? – Taladris Feb 16 '18 at 11:21
16

This seems like a very natural application for the intersections library. I personally would do this with pgfplots, using your framework as a starting point.

screenshot

\documentclass{article}

\usepackage{pgfplots}
\usetikzlibrary{intersections}
\usetikzlibrary{patterns}

\begin{document}
\begin{figure}[htpb]
    \centering
    \begin{tikzpicture}
        \begin{axis}[axis on top,smooth,
            axis line style=very thick,
            axis x line=bottom,
            axis y line=left,
            ymin=-1,ymax=6,xmin=-1,xmax=6,
            xlabel=$x_1$, ylabel=$x_2$,grid=major
            ]
            \addplot[name path global=firstline,very thick, domain=-10:10]{3-x};
            \addplot[name path global=secondline,very thick, domain=-10:10]{-5+2*x};
            \addplot[name path global=thirdline,very thick, domain=-10:10]{3/2+x/2};
            \fill[name intersections={of=firstline and secondline,by=point1},
            name intersections={of=firstline and thirdline,by=point2},
            name intersections={of=secondline and thirdline,by=point3},
            ][very thick,draw=orange,pattern=crosshatch dots,pattern color=green!60!white](point1)--(point2)--(point3)--(point1);
        \end{axis}
    \end{tikzpicture}
    \caption{Problem 4, Part A}
    \label{fig:p3:c1}
\end{figure}

\end{document}

Note that your \label should always go after your \caption.

Note that you need to use name path global as detailed in Intersections in PGFplots

Animation

Just for fun, here's an animation

animation

\documentclass[tikz]{standalone}

\usepackage{pgfplots}
\usetikzlibrary{intersections}
\usetikzlibrary{patterns}

\begin{document}
\foreach \m in{0.5,1,...,5,4.5,4,3.5,3,2.5,2,1.5,1,0.5}{%
    \begin{tikzpicture}
        \begin{axis}[axis on top,smooth,
            axis line style=very thick,
            axis x line=bottom,
            axis y line=left,
            ymin=-1,ymax=6,xmin=-1,xmax=6,
            xlabel=$x_1$, ylabel=$x_2$,grid=major
            ]
            \addplot[name path global=firstline,very thick,red, domain=-10:10]{\m-x};
            \addplot[name path global=secondline,very thick, domain=-10:10]{-5+2*x};
            \addplot[name path global=thirdline,very thick, domain=-10:10]{3/2+x/2};
            \fill[name intersections={of=firstline and secondline,by=point1},
            name intersections={of=firstline and thirdline,by=point2},
            name intersections={of=secondline and thirdline,by=point3},
            ][very thick,draw=orange,pattern=crosshatch dots,pattern color=green!60!white](point1)--(point2)--(point3)--(point1);
        \end{axis}
    \end{tikzpicture}
    }
\end{document}

See How to convert pstricks animation to GIF file? for full details of the rest of the process (just a couple of steps).

cmhughes
  • 100,947
12

Just for fun.

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add,pst-eucl,graphicx}

\psset{saveNodeCoors}
\def\f(#1){#1 1 add}
\def\g#1{#1 neg 3 div 2 add}
\def\h#1{#1 neg 3 add}

\begin{document}

\begin{pspicture*}[showgrid=false](-1,-2)(4,3)
    \psset{PointName=none,PointSymbol=none}
    \pstInterFF{\f(x)}{\g{x}}{0}{A}%
    \pstInterFF{\g{x}}{\h{x}}{0}{B}%
    \pscustom[fillstyle=solid,fillcolor=yellow,opacity=0.5]{
        \psline(!0 {\f(0)}/Y ED Y)
        \psplot{0}{N-A.x}{\f(x)/Y ED Y}
        \psplot{N-A.x}{N-B.x}{\g{x}}
        \psplot{N-B.x}{2.5}{\h{x}}
        \psline(2.5,0)
        \closepath}
    \psplot{-1}{4}{\f(x)/Y ED Y}
    \psplot{-1}{4}{\g{x}}
    \psplot{-1}{4}{\h{x}}
    \psline(2.5,-2)(2.5,3)
    \psaxes[labelFontSize=\scriptscriptstyle]{->}(0,0)(-0.75,-1.75)(3.5,2.5)[$x$,0][$y$,120]
\end{pspicture*}  

\end{document}

New features:

  • \psset{saveNodeCoors}
  • \psline(!0 {\f(0)}/Y ED Y)
  • \psplot{0}{N-A.x}{\f(x)/Y ED Y}

Latest update

Infix notation is used here for the sake of your convenience.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add,pst-eucl,graphicx}


\def\f(#1){(#1+1)}
\def\g#1{(-(#1)/3+2)}
\def\h#1{(-(#1)+3)}

\pstVerb{/I2P {AlgParser cvx exec} def}

\begin{document}

\begin{pspicture*}[saveNodeCoors,PointName=none,PointSymbol=none](-1,-2)(4,3)
    \pstInterFF{{\f(x)} exec I2P}{\g{x} I2P}{0}{A}
    \pstInterFF{\g{x} I2P}{\h{x} I2P}{0}{B}
    \pscustom[fillstyle=solid,fillcolor=yellow,opacity=0.5]
        {
        \psline(*0 {\f(x)})
        \psplot{0}{N-A.x}{{\f(x)} exec I2P}
        \psplot{N-A.x}{N-B.x}{\g{x} I2P}
        \psplot{N-B.x}{2.5}{\h{x} I2P}
        \psline(2.5,0)
        \closepath
        }
    \psplot{-1}{4}{{\f(x)} exec I2P}
    \psplot{-1}{4}{\g{x} I2P}
    \psplot{-1}{4}{\h{x} I2P}
    \psline(2.5,-2)(2.5,3)
    \psaxes[labelFontSize=\scriptscriptstyle]{->}(0,0)(-0.75,-1.75)(3.5,2.5)[$x$,0][$y$,120]
\end{pspicture*}  

\end{document}
4

Needs latest pst-eucl.tex from CTAN or http://texnik.dante.de/tex/generic/pst-eucl/

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add,pst-eucl}

\def\f{x+1} \def\g{-x/3+2}  \def\h{-x+3}    
\begin{document}

\begin{pspicture*}[saveNodeCoors,algebraic,PointName=none,PointSymbol=none](-1,-2)(4,3)
    \pstInterFF{\f}{\g}{0}{A} \pstInterFF{\g}{\h}{0}{B}
    \pscustom[fillstyle=solid,fillcolor=yellow,opacity=0.5]{
        \psline(*0 {\f})
        \psplot{0}{N-A.x}{\f}
        \psplot{N-A.x}{N-B.x}{\g}
        \psplot{N-B.x}{2.5}{\h}
        \psline(2.5,0) }
    \psaxes[labelFontSize=\scriptscriptstyle]{->}(0,0)(-0.75,-1.75)(3.5,2.5)[$x$,0][$y$,120]
    \psset{linecolor=black!40}
    \psplot{-1}{4}{\f}
    \psplot{-1}{4}{\g}
    \psplot{-1}{4}{\h}
    \psline(2.5,-2)(2.5,3)
\end{pspicture*}  

\end{document}

enter image description here