![如何在 pgfplots 中为某个区域着色?](https://linux22.com/image/273951/%E5%A6%82%E4%BD%95%E5%9C%A8%20pgfplots%20%E4%B8%AD%E4%B8%BA%E6%9F%90%E4%B8%AA%E5%8C%BA%E5%9F%9F%E7%9D%80%E8%89%B2%EF%BC%9F.png)
如何在由图相交创建的多边形中创建阴影区域?在这种情况下,直到没有圆圈标记的实线。
\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}
答案1
虽然解决方案不那么优雅,但对于这种简单的情况来说,这是更快捷的方法。
\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}
答案2
pgfplots 1.10 版刚刚发布,它为填充图表之间区域的问题提供了新的解决方案。
请注意,旧解决方案仍然可行且有效;此处仅提供可能简化任务的更新。为了使本网站的知识库保持最新,我fillbetween
在此提供基于新库的解决方案:
\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}
关键是标记这两个函数并添加\addplot fill between
。请注意,将split
交点拆分为多个段,every segment no 1
并使第二段不可见(此处索引从 0 开始)。
答案3
更自动化的方法是使用堆叠图:首先,绘制一个定义下边界的不可见图,然后将要绘制的区域堆叠在顶部。
如果您以表格而不是坐标流的形式提供数据,这是最简单的:
\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
在此示例中,astruct ShadedArea
在环境中定义asydef
。它采用数据值数组points
、垂直偏移dy
、水平高度wlheight
和限制x
并y
绘制图。着色分两步完成:
1) 水平线下方的区域以阴影表示,
2) 移位图下方的区域y
以填充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`.