我想对x=y^2 -1
和之间的区域进行阴影处理x=1-y^2
。我希望能够编写类似以下代码:
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{every axis/.append style={
axis x line=middle, % put the x axis in the middle
axis y line=middle, % put the y axis in the middle
axis line style={->,color=blue}, % arrows on the axis
every x tick label/.append style={
font=\scriptsize\sffamily,
yshift=0.75ex,rotate=0},
every y tick label/.append style={
font=\scriptsize\sffamily,
xshift=0.75ex,
},
every axis x label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},
every axis y label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel,rotate=90},
},
x=0.75cm,
y=0.75cm,
}
\usepgfplotslibrary{fillbetween}
\newcommand\aefuncA{ x^2 - 1 }
\newcommand\aefuncB{ 1 - x^2 }
\begin{document}
\begin{tikzpicture}
\begin{axis}[
%<only applies to titles but not tick labels>% font=\sffamily,
% title={graph of $y=\aefuncA$},
xticklabel={\pgfmathprintnumberto{\tick}{\aetmp}{$\mathbf{\aetmp}$}},
yticklabel={\pgfmathparse{int(\tick)}\ifdim\pgfmathresult pt=0pt 100\else\pgfmathprintnumber{\tick}\fi},
%%yticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
xlabel={},
ylabel={},
xmin=-3,xmax=3,
ymin=-3,ymax=3,
grid=both,
xtick={-4,-3,...,4},
ytick={-3,-2,-1,0,...,3},
]
\addplot [domain=-3:3,samples=64,name path=f]({\aefuncA},{x});
\addplot [domain=-3:3,samples=64,name path=g]({\aefuncB},{x});
\path [name path=axis] (axis cs:-2,0) -- (axis cs:2,0);
\addplot [thick,color=blue,fill=blue,fill opacity=0.25]
fill between[of=f and g,
soft clip={domain=-1:1}];
\end{axis}
\end{tikzpicture}
\end{document}
但这会导致:
手册似乎表明我不能直接做我想做的事情。(第 378 页说each x coordinate has at most one y coordinate
)有没有办法交换 x 轴和 y 轴的角色?
而在这个特定的例子中,可以重新参数化以获得所需的效果
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{every axis/.append style={
axis x line=middle, % put the x axis in the middle
axis y line=middle, % put the y axis in the middle
axis line style={->,color=blue}, % arrows on the axis
every x tick label/.append style={
font=\scriptsize\sffamily,
yshift=0.75ex,rotate=0},
every y tick label/.append style={
font=\scriptsize\sffamily,
xshift=0.75ex,
},
every axis x label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},
every axis y label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel,rotate=90},
},
x=0.75cm,
y=0.75cm,
}
\usepgfplotslibrary{fillbetween}
\newcommand\aefuncA{ (x+1)^(1/2) }
\newcommand\aefuncB{ -(x+1)^(1/2) }
\newcommand\aefuncC{ (1-x)^(1/2) }
\newcommand\aefuncD{ -(1-x)^(1/2) }
\begin{document}
\begin{tikzpicture}
\begin{axis}[
%<only applies to titles but not tick labels>% font=\sffamily,
% title={graph of $y=\aefuncA$},
xticklabel={\pgfmathprintnumberto{\tick}{\aetmp}{$\mathbf{\aetmp}$}},
yticklabel={\pgfmathparse{int(\tick)}\ifdim\pgfmathresult pt=0pt 100\else\pgfmathprintnumber{\tick}\fi},
%%yticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
xlabel={},
ylabel={},
xmin=-3,xmax=3,
ymin=-3,ymax=3,
grid=both,
xtick={-4,-3,...,4},
ytick={-3,-2,-1,0,...,3},
]
\addplot [domain=-1:3,samples=64,name path=f]({x},{\aefuncA});
\addplot [domain=-1:3,samples=64,name path=g]({x},{\aefuncB});
\addplot [domain=-3:1,samples=64,name path=c]({x},{\aefuncC});
\addplot [domain=-3:1,samples=64,name path=d]({x},{\aefuncD});
\path [name path=axis] (axis cs:-2,0) -- (axis cs:2,0);
\addplot [thick,color=blue,fill=blue,fill opacity=0.25]
fill between[of=f and g,
soft clip={domain=-1:0}];
\addplot [thick,color=blue,fill=blue,fill opacity=0.25]
fill between[of=c and d,
soft clip={domain=0:1}];
\end{axis}
\end{tikzpicture}
\end{document}
并非所有我希望创建的图表都能如此轻易地重写。
那么,有没有办法判断pgfplots
(或诡计 pgfplots
) 分为y
作为独立变量和x
作为因变量?
答案1
您必须在示例中使用domain y=-1:1
作为参数。这意味着您必须限制。soft clip
y
x
我将x=y^2-4
在x=4-y^2
我的示例中使用:
代码:
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\pgfplotsset{
every axis/.append style={
axis x line=middle, % put the x axis in the middle
axis y line=middle, % put the y axis in the middle
axis line style={->,color=blue}, % arrows on the axis
every x tick label/.append style={
font=\scriptsize\sffamily,
yshift=0.75ex,rotate=0},
every y tick label/.append style={
font=\scriptsize\sffamily,
xshift=0.75ex,
},
every axis x label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},
every axis y label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel,rotate=90},
},
x=0.75cm,
y=0.75cm,
}
\usepgfplotslibrary{fillbetween}
\newcommand\aefuncA{ x^2 - 4 }
\newcommand\aefuncB{ 4 - x^2 }
\begin{document}
\begin{tikzpicture}
\begin{axis}[
%<only applies to titles but not tick labels>% font=\sffamily,
%title={graph of $y=\aefuncA$},
xticklabel={\pgfmathprintnumberto{\tick}{\aetmp}{$\mathbf{\aetmp}$}},
yticklabel={\pgfmathparse{int(\tick)}\ifdim\pgfmathresult pt=0pt 100\else\pgfmathprintnumber{\tick}\fi},
yticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
xlabel={},
ylabel={},
xmin=-7,xmax=7,
ymin=-3,ymax=3,
grid=both,
xtick={-7,-6,...,7},
ytick={-3,-2,...,3},
]
\addplot [domain=-3:3,samples=64,name path=f]({\aefuncA},{x});
\addplot [domain=-3:3,samples=64,name path=g]({\aefuncB},{x});
\addplot [fill=blue,fill opacity=0.25]fill between[
of=f and g,
soft clip={domain y=-2:2}
];
\end{axis}
\end{tikzpicture}
\end{document}
如果你不知道交点,你可以使用
\addplot[fill=none] fill between [
of=f and g,
split,
every segment no 1/.style={fill=red,fill opacity=0.25}
];
这是另一个使用x=y^2-3
和的例子x=3-y^2
代码:
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\pgfplotsset{
every axis/.append style={
axis x line=middle, % put the x axis in the middle
axis y line=middle, % put the y axis in the middle
axis line style={->,color=blue}, % arrows on the axis
every x tick label/.append style={
font=\scriptsize\sffamily,
yshift=0.75ex,rotate=0},
every y tick label/.append style={
font=\scriptsize\sffamily,
xshift=0.75ex,
},
every axis x label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel},
every axis y label/.style={at={(ticklabel cs:0.5)},anchor=near ticklabel,rotate=90},
},
x=0.75cm,
y=0.75cm,
}
\usepgfplotslibrary{fillbetween}
\newcommand\aefuncA{ x^2 - 3 }
\newcommand\aefuncB{ 3 - x^2 }
\begin{document}
\begin{tikzpicture}
\begin{axis}[
%<only applies to titles but not tick labels>% font=\sffamily,
%title={graph of $y=\aefuncA$},
xticklabel={\pgfmathprintnumberto{\tick}{\aetmp}{$\mathbf{\aetmp}$}},
yticklabel={\pgfmathparse{int(\tick)}\ifdim\pgfmathresult pt=0pt 100\else\pgfmathprintnumber{\tick}\fi},
yticklabel={\pgfmathprintnumber[assume math mode=true]{\tick}},
xlabel={},
ylabel={},
xmin=-5,xmax=5,
ymin=-3,ymax=3,
grid=both,
xtick={-5,-4,...,5},
ytick={-3,-2,...,3},
]
\addplot [domain=-3:3,samples=64,name path=f]({\aefuncA},{x});
\addplot [domain=-3:3,samples=64,name path=g]({\aefuncB},{x});
\addplot[fill=none] fill between [
of=f and g,
split,
every segment no 1/.style={fill=red,fill opacity=0.25}
];
\end{axis}
\end{tikzpicture}
\end{document}
答案2
为了说明 Bernard 和我本人在评论中提到的两种不同方法,以及我认为可以帮助解决这个问题pgfplots
或使用任何喜欢的绘图引擎的方法,我分别使用 MetaPost 及其 TeX 界面制作了这张图片mfpic
。
首先,使用 MetaPost,使用参数图。我使用了一些我自己的宏,我在这里重现了它们。
input mpcolornames ;
input latexmp ;
setupLaTeXMP(textextlabel = enable, mode = rerun) ;
% Grid lines
vardef gridlines (expr xunit, yunit)(expr xmin, xmax, xstep)(expr ymin, ymax, ystep) =
image(for x = ceiling(xmin) upto floor(xmax):
draw ((x, ymin) -- (x, ymax)) xscaled xunit yscaled yunit ;
endfor ;
for y = ceiling(ymin) upto floor(ymax):
draw ((xmin, y) -- (xmax, y)) xscaled xunit yscaled yunit ;
endfor ;)
enddef ;
% Macro creating a parametric curve
vardef param_curve (expr tmin, tmax, tsep)(text x_t)(text y_t) =
save f, g; vardef f(expr t) = x_t enddef ; vardef g(expr t) = y_t enddef ;
(f(tmin), g(tmin))
for t = tmin+tsep step tsep until (tmax+0.9tsep): .. (f(t), g(t)) endfor
enddef ;
% Parameters
numeric u ; u = cm ;
numeric tmin, tmax, tsep ; tmin = -2 ; tmax = 2 ; tsep = 0.1 ;
numeric xmin, xmax, ymin, ymax ; xmax = ymax = -xmin = -ymin = 3 ;
beginfig(1) ;
% Curves (definitions)
path curve[] ;
curve1 = param_curve(-2, 2, 0.1)(1-t**2)(t) ;
curve2 = param_curve(-2, 2, 0.1)(t**2-1)(t) ;
% Detects the borders of the area between curves, and fills it
fill buildcycle(curve1, reverse curve2) scaled u withcolor 0.75[blue, white];
% Grid
draw gridlines(u, u)(xmin, xmax, 1)(ymin, ymax, 1) withcolor 0.75white ;
% Axes
drawarrow (u*xmin, 0) -- (u*xmax, 0) ; drawarrow (0, u*ymin) -- (0, u*ymax) ;
% Curves (drawing)
for i = 1, 2: draw curve[i] scaled u ; endfor ;
% Labels
for x = ceiling(xmin) upto floor(xmax) :
if x <> 0: label.bot("$" & decimal x & "$", (x*u, 0)); fi ;
endfor ;
for y = ceiling(ymin) upto floor(ymax) :
if y <> 0: label.lft("$" & decimal y & "$", (0, u*y)); fi ;
endfor ;
setbounds currentpicture to boundingbox currentpicture enlarged 3bp;
endfig ;
end.
使用 LaTeX 作为排版引擎,使用 MetaPost 的 Metafun 格式进行编译。通常我更喜欢使用 MPtoPDF 实用程序直接生成 PDF 图像:
mptopdf --tex=latex --mem=metafun thisgraph.mp
第二次尝试,使用mfpic
软件包,为 MetaPost(或 METAFONT)提供一个 (La)TeX 接口,这次使用对称性。比直接使用 MetaPost 更简洁,因为有用的宏已经由软件包本身定义(而且 LaTeX 通常比 MetaPost 更简洁 — — 但不一定更简单)。
\documentclass{article}
\usepackage[metapost, clip, overlaylabels]{mfpic}
\setlength{\mfpicunit}{1cm}
\opengraphsfile{\jobname}
\begin{document}
\begin{mfpic}[1]{-3}{3}{-3}{3}
% The functions
\fdef{f}{x}{x**2-1}
\fdef{g}{x}{1-x**2}
% Grid
\drawcolor[gray]{0.75}
\gridlines{1, 1}
% Area between curves - swapping x and y
\drawcolor{black}
\begin{coords}
\xyswap
\fillcolor{0.75[blue,white]}
\gfill\btwnfcn{-1, 1, 0.1}{f(x)}{g(x)}
\function{\xmin, \xmax, 0.1}{f(x)}
\function{\xmin, \xmax, 0.1}{g(x)}
\end{coords}
% Axes and labels
\doaxes{xy}
\tlpointsep{3bp}
\axislabels{x}{{$-3$}-3, {$-2$}-2, {$-1$}-1, {$1$}1, {$2$}2, {$3$}3}
\axislabels{y}{{$-3$}-3, {$-2$}-2, {$-1$}-1, {$1$}1, {$2$}2, {$3$}3}
\end{mfpic}
\closegraphsfile
\end{document}
使用 (PDF/Xe/Lua)LaTeX 进行编译,然后使用 MetaPost 进行编译,最后再次使用 LaTeX 进行编译。