Tikz 和 pgfplot 绘图问题

Tikz 和 pgfplot 绘图问题

我正在使用 pgfplots。图表在不该被剪裁的地方被剪裁了,我该如何修复?

\documentclass{article}

\usepackage{tikz}
\usepackage{siunitx}
\usepackage{pgfplots}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}[
        ymin=0,ymax=0.33,
        xmin=0,xmax=260,
        ticks=none,axis x line=bottom,axis y line=left,xlabel={Voltage (\si{\volt})}, ylabel={Current (\si{\ampere})},
    ]
    \addplot[
        domain=0:249.999,
        samples=1000,
    ]
        {0.0257019* ln(1000 *(250 - x))};
    \end{axis}
    \end{tikzpicture}
\end{document}

函数图像被截断了,但是应该到达 x 轴

由于图表在 250 附近比较陡峭,我想在 (250,0) 处添加一个点,以便 pgfplots 可以绘制一条垂直线,我一直试图这样做,但没有成功。这是真实的例子:

\documentclass{article}

\usepackage{tikz}
\usepackage{siunitx}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}[
    declare function={
        func(\x)= (\x<250) * 0.02570194444* ln(1.470588235e10 -5.882352941e7* \x)) +
            (\x==250)*(0);
    }
]
    \begin{axis}[
        clip=false,
        ymin=0,ymax=0.625,
        xmin=0,xmax=260,
        every axis y label/.style={
            at={(ticklabel* cs:0.5)},
            anchor=near ticklabel,
            rotate=90,
        },
        every axis x label/.style={
            at={(ticklabel* cs:0.5)},
            anchor=near ticklabel,
        },
        ticks=none,
        xlabel={Voltage (\si{\volt})}, ylabel={Current (\si{\ampere})},
        ]

        \addplot[domain=0:250,samples=3000,thick]{func(x)};
    \end{axis}
\end{tikzpicture}
\end{document}

实图

我怎样才能做到这一点?

答案1

这个问题与tikz 无法正确绘图(关于 TikZ 绘图功能):由于数值不准确,有时域的采样不能达到指定的上限。

为了解决这个问题,必须教会 PGFPlots 始终使用指定的上限(使用 给出domain=<lower>:<uppper>),而不是计算值(使用 确定<lower> + <samples> * <step size>。在 PGFPlots 中,这可以通过修补 中使用的内部宏来实现\pgfplotforeachungrouped,它是该函数的变体\foreach

\documentclass{article}

\usepackage{pgfplots}

\makeatletter
\long\def\pgfplotsforeachungroupeduniform@#1#2,#3,...,#4\relax#5{%
    % Compute mesh width!
    \pgfmathparse{#2}%
    \let\pgfplots@foreach@loc@TMPa=\pgfmathresult
    \pgfmathparse{#3}%
    \let\pgfplots@foreach@loc@TMPb=\pgfmathresult
    \pgfmathsubtract@{\pgfplots@foreach@loc@TMPb}{\pgfplots@foreach@loc@TMPa}%
    % Use \pgfmath engine for the loop:
    % mesh width:
    \let\pgfplots@foreach@loc@meshwidth=\pgfmathresult
    \pgfmathparse{0}% invoke the parser - in case the fpu is active.
    \pgfmathlessthan@{\pgfplots@foreach@loc@meshwidth}{\pgfmathresult}%
    % the loop will run while ( NOT \pgfplots@foreach@loc@cmp{<cur>}{<last>} )
    \ifdim\pgfmathresult pt=1pt
        \def\pgfplots@foreach@loc@cmp{\pgfmathlessthan@}%
    \else
        \def\pgfplots@foreach@loc@cmp{\pgfmathgreaterthan@}%
    \fi
    %
    \pgfmathparse{#4 - 0.5*\pgfplots@foreach@loc@meshwidth}% Do the iteration only up to the penultimate value
    \let\pgfplots@foreach@loc@TMPb=\pgfmathresult
    %
    \t@pgfplots@toka={#5}%
    % to allow nesting without additional TeX groups of
    % \pgfplotsforeachungroupeduniform, I introduce this loop
    % structure here which does not need ANY state macro:
    \edef\pgfplots@foreach@loc@TMPc{%
        \noexpand\pgfplotsforeachungroupeduniform@loop@mathengine
            {\expandafter\noexpand\pgfplots@foreach@loc@cmp}% #1= comparison fct
            {\pgfplots@foreach@loc@TMPa}% #2 =lower limit (ITERATES)
            {\pgfplots@foreach@loc@TMPb}% #3 = upper limit
            {\noexpand#1}% #4 = the loop macro name
            {\pgfplots@foreach@loc@meshwidth}% #5 =  h
            {\the\t@pgfplots@toka}% #6 = the code to invoke
    }%
    \pgfplots@foreach@loc@TMPc
    % After the iteration is done, invoke the code one last time with the value of the given upper limit
    \def#1{#4}%
    #5
}%
\makeatother



\begin{document}
    \begin{tikzpicture}
    \begin{axis}[
        ymin=0,ymax=0.33,
        xmin=0,xmax=260,
        ticks=none,axis x line=bottom,axis y line=left,xlabel={Voltage (\si{\volt})}, ylabel={Current (\si{\ampere})},
    ]
    \addplot[
        domain=0:249.9999,
        samples=100,
    ]
        {0.0257019* ln(1000 *(250 - x))};
    \addplot [domain=-1:1, samples=50] {sqrt(4*(1-(\x)^2))};
    \end{axis}
    \end{tikzpicture}
\end{document}

答案2

在此处输入图片描述

\documentclass{article}

%\usepackage{tikz}
\usepackage{siunitx}
\usepackage{pgfplots}
 \pgfplotsset{compat=1.9}
\begin{document}
    \begin{tikzpicture}
    \begin{axis}[
        ymin=0,ymax=0.33,
        xmin=0,xmax=260,
        ticks=none,axis x line=bottom,axis y line=left,xlabel={Voltage (\si{\volt})}, ylabel={Current (\si{\ampere})},
    ]
    \addplot[
        domain=0:250,
        samples=1000,
    ]
    { (0.0257019* ln(1000 *(250 - x)))*(x<249.9)+0};
    \end{axis}
    \end{tikzpicture}
\end{document}

答案3

问题似乎是由于函数变化非常快,因此使用的点数有限pgfplots,并且您指定的域不够宽。通过将图分成两部分,您可以更好地控制pgfplots应用于每个部分的点数。我还必须将第二个图的域增加到249.9999而不是249.999。不过,这是一种相当蛮力的方法,我希望有更好的方法……无论如何,以下方法对我和 都pdflatex有效lualatex

% arara: pdflatex
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
    \begin{tikzpicture}
    \begin{axis}[
        ymin=0,ymax=0.33,
        xmin=0,xmax=260,
        ticks=none,axis x line=bottom,axis y line=left,
    ]
    \addplot[
        domain=0:240,
        samples=1000,
    ]
        {0.0257019* ln(1000 *(250 - x))};
    \addplot[
        domain=240:249.9999,
        samples=1000,
    ]
        {0.0257019* ln(1000 *(250 - x))};
    \end{axis}
    \end{tikzpicture}
\end{document}

圖形像

相关内容