两条曲线之间的面积是 y 函数,而不是 x 函数

两条曲线之间的面积是 y 函数,而不是 x 函数

我想对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 clipyx

我将x=y^2-4x=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 进行编译。

在此处输入图片描述

相关内容