Tell me more ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to hatch the area under a curve (graph of a function) with oblique lines on an interval (to illustrate the function's integral on that interval). This can be done elegantly in gnuplot... enter image description here

...but I simply cannot reproduce this with pgfplots. The only solution I managed to find with google is the use of the patterns tikz library, however it is unacceptibly ugly:

enter image description here

I'm not aware of any way to alter the color, line width and - especially - the distance between the hatching lines when patterns library is employed. Is there any way to set it? (So that I can change it to resemble the gnuplot version.)

Or, should I choose a completely different approach to reproduce the gnuplot-style hatching...?

Also note that

  • pgfplots changes the color of the x-axis to red on the interval (which is not a critical problem, of course, but not elegant).
  • the legend for the filling is much more logical in case of gnuplot. Can I reproduce it with pgfplots?

Here is the code I currently use:

\begin{figure}[ht!]
\centering
\begin{tikzpicture}
    \begin{axis}[xmin=-4,xmax=4,xlabel={z},ymin=0,ymax=1] 
    \addplot[color=red,domain=-4:4,samples=100] {1/sqrt(2*pi)*exp(-x^2/2)};
    \addlegendentry{z}
    \addplot[color=red,fill=red, pattern=north east lines,  domain=0:1,samples=100] {1/sqrt(2*pi)*exp(-x^2/2)} \closedcycle;
    \addlegendentry{Interval}
    \end{axis}
\end{tikzpicture}
\end{figure}
share|improve this question

2 Answers

up vote 24 down vote accepted

You can define your own pattern that can take optional arguments for setting the distance between the lines and the line thickness.

To make sure the axis line stays black, you can set axis on top, which will draw the axis lines last.

And to get the hatch pattern in the legend as well, add the key area legend to the plot:

 \documentclass{article}
    \usepackage{tikz}
    \usetikzlibrary{patterns}
    \usepackage{pgfplots}
    \begin{document}
    \begin{tikzpicture}
    \tikzset{
        hatch distance/.store in=\hatchdistance,
        hatch distance=10pt,
        hatch thickness/.store in=\hatchthickness,
        hatch thickness=2pt
    }

    \makeatletter
    \pgfdeclarepatternformonly[\hatchdistance,\hatchthickness]{flexible hatch}
    {\pgfqpoint{0pt}{0pt}}
    {\pgfqpoint{\hatchdistance}{\hatchdistance}}
    {\pgfpoint{\hatchdistance-1pt}{\hatchdistance-1pt}}%
    {
        \pgfsetcolor{\tikz@pattern@color}
        \pgfsetlinewidth{\hatchthickness}
        \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}
        \pgfpathlineto{\pgfqpoint{\hatchdistance}{\hatchdistance}}
        \pgfusepath{stroke}
    }

    \begin{axis}[
        xmin=-4,xmax=4,
        xlabel={z},
        ymin=0,ymax=1,
        axis on top,
        legend style={legend cell align=right,legend plot pos=right}] 
    \addplot[color=red,domain=-4:4,samples=100] {1/sqrt(2*pi)*exp(-x^2/2)};
    \addlegendentry{z}
    \addplot+[mark=none,
        domain=0:1,
        samples=100,
        pattern=flexible hatch,
        area legend,
        pattern color=red]{1/sqrt(2*pi)*exp(-x^2/2)} \closedcycle;
    \addlegendentry{Interval 1}
    \addplot+[mark=none,
        domain=-2:-0.5,
        samples=100,
        pattern=flexible hatch,
        hatch distance=5pt,
        hatch thickness=0.5pt,
        draw=blue,
        pattern color=cyan,
        area legend]{1/sqrt(2*pi)*exp(-x^2/2)} \closedcycle;    
        \addlegendentry{Interval 2}
    \end{axis}
\end{tikzpicture}
\end{document}
share|improve this answer
Thank you very much! Works perfectly, you addressed every problem! Just one quick (and very minor) additional question, if your time permits: is there any way to change the order within legend, so that is also identical to the gnuplot-style? I.e. text first (flushed to the right), and then (on the right side) the line/area. – Tamas Ferenci Sep 24 '11 at 16:06
Your alignment question should be possible by means of legend style={legend cell align=right,legend plot pos=right}. – Christian Feuersänger Sep 24 '11 at 17:36
@Christian: Yup, that does it! – Jake Sep 24 '11 at 23:53
Exactly. Works as a wonder; now we have covered every aspect of this question. Thank you all again! – Tamas Ferenci Sep 25 '11 at 8:34
@Jake I was wondering, can you easily set the lines to be opposite (like \ versus /?) So that if you overlapped them they would both be easily visible (using thin lines)? – Alenanno Apr 6 at 10:47
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{patterns}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\pgfdeclarepatternformonly{north east lines wide}%
   {\pgfqpoint{-1pt}{-1pt}}%
   {\pgfqpoint{10pt}{10pt}}%
   {\pgfqpoint{9pt}{9pt}}%
   {
     \pgfsetlinewidth{0.4pt}
     \pgfpathmoveto{\pgfqpoint{0pt}{0pt}}
     \pgfpathlineto{\pgfqpoint{9.1pt}{9.1pt}}
     \pgfusepath{stroke}
    }

    \begin{axis}[xmin=-4,xmax=4,xlabel={z},ymin=0,ymax=1] 
    \addplot[color=red,domain=-4:4,samples=100] {1/sqrt(2*pi)*exp(-x^2/2)};
    \addlegendentry{z}
    \addplot+[mark=none,domain=0:1,samples=100,%
              pattern=north east lines wide,%
              pattern color=red!50!yellow]%
              {1/sqrt(2*pi)*exp(-x^2/2)}
              \closedcycle;
    \addlegendentry{Interval}
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
Thank you very much! – Tamas Ferenci Sep 24 '11 at 16:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.