10

How do I create a shaded area in a polygon created by plot intersections? In this case, up to the solid line without circle marks.

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{figure}[htb]
\centering
\begin{tikzpicture}
\begin{axis}[
enlarge x limits=false,
axis on top,
enlarge y limits=true,
ymin=0,
symbolic x coords={Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec},
xtick=data,
]

\addplot[dashed] coordinates
{(Jan,5.5) (Feb,5.5) (Mar,5.5) (Apr,5.5) (May,5.5) (Jun,5.5) (Jul,5.5) (Aug,5.5) (Sep,5.5) (Oct,5.5) (Nov,5.5) (Dec,5.5)};

\addplot [black,mark=circle] coordinates
{(Jan,3.2) (Feb,4) (Mar,4.5) (Apr,4.7) (May,5.5) (Jun,6.7) (Jul,6.5) (Aug,5.5) (Sep,4.7) (Oct,4.5) (Nov,4) (Dec,3.2)};

\addplot [black,mark=*,mark options=solid] coordinates
{(Jan,3) (Feb,3.8) (Mar,4.3) (Apr,4.5) (May,5.3) (Jun,6.5) (Jul,6.3) (Aug,5.3) (Sep,4.5) (Oct,4.3) (Nov,3.8) (Dec,3)};

\end{axis}
\end{tikzpicture}
\end{figure}

\end{document}

enter image description here

9

Not so elegant as solution but for this simple situation is the quicker way.

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{figure}[htb]
\centering
\begin{tikzpicture}
\begin{axis}[
enlarge x limits=false,
axis on top,
enlarge y limits=true,
ymin=0,
symbolic x coords={Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec},
xtick=data,
]

\addplot [black,mark=*,mark options=solid] coordinates
{(Jan,3) (Feb,3.8) (Mar,4.3) (Apr,4.5) (May,5.3) (Jun,6.5) (Jul,6.3) (Aug,5.3) (Sep,4.5) (Oct,4.3) (Nov,3.8) (Dec,3)};

\addplot[fill=lightgray,draw=none] coordinates {(Jan,3.2) (Jan,5.5) (May,5.5) (Apr,4.7) (Mar,4.5) (Feb,4) (Jan,3.2) } \closedcycle;

\addplot[fill=lightgray,draw=none] coordinates {(Dec,5.5) (Dec,3.2)  (Nov,4) (Oct,4.5) (Sep,4.7) (Aug,5.5) (Dec,5.5)} \closedcycle;

\addplot[dashed] coordinates
{(Jan,5.5) (Feb,5.5) (Mar,5.5) (Apr,5.5) (May,5.5) (Jun,5.5) (Jul,5.5) (Aug,5.5) (Sep,5.5) (Oct,5.5) (Nov,5.5) (Dec,5.5)};

\addplot [black,mark=circle] coordinates
{(Jan,3.2) (Feb,4) (Mar,4.5) (Apr,4.7) (May,5.5) (Jun,6.7) (Jul,6.5) (Aug,5.5) (Sep,4.7) (Oct,4.5) (Nov,4) (Dec,3.2)};

\end{axis}
\end{tikzpicture}
\end{figure}

\end{document}

enter image description here

  • If it works, it works :) – percusse Aug 21 '13 at 19:15
10

Version 1.10 of pgfplots has been released just recently, and it comes with a new solution for the problem to fill the area between plots.

Note that the old solution is still possible and still valid; this here is merely an update which might simplify the task. In order to keep the knowledge base of this site up-to-date, I present a solution based on the new fillbetween library here:

\documentclass{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.9}

\usepgfplotslibrary{fillbetween}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
enlarge x limits=false,
axis on top,
enlarge y limits=true,
ymin=0,
symbolic x coords={Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec},
xtick=data,
]

\addplot[name path=dashed,dashed] coordinates
{(Jan,5.5) (Feb,5.5) (Mar,5.5) (Apr,5.5) (May,5.5) (Jun,5.5) (Jul,5.5) (Aug,5.5) (Sep,5.5) (Oct,5.5) (Nov,5.5) (Dec,5.5)};

\addplot [name path=line,black,mark=circle] coordinates
{(Jan,3.2) (Feb,4) (Mar,4.5) (Apr,4.7) (May,5.5) (Jun,6.7) (Jul,6.5) (Aug,5.5) (Sep,4.7) (Oct,4.5) (Nov,4) (Dec,3.2)};

\addplot [black,mark=*,mark options=solid] coordinates
{(Jan,3) (Feb,3.8) (Mar,4.3) (Apr,4.5) (May,5.3) (Jun,6.5) (Jul,6.3) (Aug,5.3) (Sep,4.5) (Oct,4.3) (Nov,3.8) (Dec,3)};

\addplot[orange!40] fill between[of=dashed and line,
    split,
    every segment no 1/.style={fill=none},
];

\end{axis}
\end{tikzpicture}
\end{document}

The key is to label the two functions and add an \addplot fill between. Note that split splits the intersection into segments and every segment no 1 renders the second segment invisible (indexing starts at 0 here).

enter image description here

7

A more automatic way of doing this is to use a stacked plot: First, you draw an invisible plot that defines the lower boundary, and then you stack the area to be drawn on top.

This is easiest if you provide your data in the form of a table instead of a stream of coordinates:

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=newest}

\pgfplotstableread{
Month DataA DataB DataC
Jan 5.5 3.2 3
Feb 5.5 4   3.8
Mar 5.5 4.5 4.3
Apr 5.5 4.7 4.5
May 5.5 5.5 5.3
Jun 5.5 6.7 6.5
Jul 5.5 6.5 6.3
Aug 5.5 5.5 5.3
Sep 5.5 4.7 4.5
Oct 5.5 4.5 4.3
Nov 5.5 4   3.8
Dec 5.5 3.2 3
}\datatable

\begin{document}

\begin{tikzpicture}
\begin{axis}[
enlarge x limits=false,
axis on top,
enlarge y limits=true,
ymin=0,
xtick=data,
xticklabels from table={\datatable}{Month},
xtick=data,
table/x expr=\coordindex
]

\addplot[dashed] table {\datatable};
\addplot [black,mark=circle] table [y=DataB] {\datatable};
\addplot [black,mark=*,mark options=solid] table [y=DataC] {\datatable};

% "Phantom plot" defining the lower boundary of the filled area
\addplot [stack plots=y, draw=none, forget plot]
    table [y expr={min(\thisrow{DataA}, \thisrow{DataB})}]
    {\datatable};

% Plot stacked on top of the phantom plot to fill the area
\addplot [stack plots=y, draw=none, fill=orange!40]
    table [y expr={\thisrow{DataA}-min(\thisrow{DataA}, \thisrow{DataB})}
    {\datatable} \closedcycle;
\end{axis}
\end{tikzpicture}
\end{document}
4

enter image description here

In this example a struct ShadedArea is defined in asydef environment. It takes an array of data values points, vertical offset dy, level height wlheight and x, y limits and draws a plot. The shading is done in two steps:

1) the area under the level line is shaded,
2) the area under the y-shifted graph is filled with white.

% s.tex:
\documentclass{article}
\usepackage{subcaption}
\usepackage{lmodern}
\usepackage[inline]{asymptote}
\usepackage[left=2cm,right=2cm]{geometry}
\begin{asydef}
import graph;

struct ShadedArea{
  real[] points;
  real dy,wlheight;
  real xmin, xmax;
  real ymin, ymax;

  int[] nmonth=sequence(12);
  string[] month={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

  void draw(){
    xlimits(xmin,xmax,crop=true);
    ylimits(ymin,ymax,crop=true);

    guide g=graph(nmonth,points);
    guide q=shift(0,dy)*g;
    guide wl=(xmin,wlheight)--(xmax,wlheight);

    pen dataLinePen=orange+1bp;
    pen upperLinePen=lightblue+1bp;
    pen levelLinePen=blue+dashed+1bp;

    fill(wl--(xmax,ymin)--(xmin,ymin)--cycle,lightblue);
    fill(q--(xmax,ymin)--(xmin,ymin)--cycle,white);

    xaxis("",BottomTop,LeftTicks(
      new string(real x) {return month[round(x % 12)];}
      ,Step=1)
      ,above=true
    );
    yaxis("",LeftRight,RightTicks(Step=2),above=true);

    draw(g,dataLinePen);
    //draw(q,upperLinePen);
    draw(wl,levelLinePen);
    draw(g,marker(scale(2)*unitcircle,red,FillDraw(white),above=true));
  }
  void operator init(real[] points,real dy,real wlheight,real xmin,real xmax,real ymin,real ymax){
    this.points=copy(points);
    this.dy       = dy      ;      
    this.wlheight = wlheight;
    this.xmin     = xmin    ;
    this.xmax     = xmax    ;
    this.ymin     = ymin    ;
    this.ymax     = ymax    ;
    draw();
  }
}
\end{asydef}

\begin{document}
%
\begin{figure}
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{0.49\textwidth}
\begin{asy}
size(8cm);
defaultpen(fontsize(10pt));
real[] points={3,3.8,4.3,4.5,5.3,6.5,6.3,5.3,4.5,4.3,3.8,3};
real dy=0.2;
real wlheight=5.7;
real xmin=0, xmax=11;
real ymin=-0.5, ymax=7;
ShadedArea(points, dy, wlheight, xmin, xmax, ymin, ymax);
\end{asy}
%
\caption{Two shaded regions, $d_y=0.2$}
\label{fig:1a}
\end{subfigure}
%
\begin{subfigure}{0.49\textwidth}
\begin{asy}
size(8cm);
defaultpen(fontsize(10pt));
real[] points={3,3.8,4.3,4.5,5.3,6.5,4.5,5.8,4.5,4.3,3.8,3};
real dy=0.1;
real wlheight=5.1;
real xmin=0, xmax=11;
real ymin=-0.5, ymax=7;
ShadedArea(points, dy, wlheight, xmin, xmax, ymin, ymax);
\end{asy}
%
\caption{Three shaded regions, $d_y=0.1$}
\label{fig:1b}
\end{subfigure}
\end{figure}
%
\end{document}
% To process it with `latexmk`, create file `latexmkrc`:
% 
%     sub asy {return system("asy '$_[0]'");}
%     add_cus_dep("asy","eps",0,"asy");
%     add_cus_dep("asy","pdf",0,"asy");
%     add_cus_dep("asy","tex",0,"asy");
% 
% and run `latexmk -pdf s.tex`.

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.