我尝试绘制函数 $2^f(x)$,其中 $f(x)$ 是分段函数。$f$ 由一组坐标给出,即:
\addplot[blue,line width=1pt,rounded corners=1pt] coordinates {
(-6,4)
(-2,0)
(-1,0)
(0,-3)
(1,1)
(2,0)
(3,1)
};
有没有办法使用给定的坐标得到 $2^f(x)$?
这里是代码和输出:
当前的
但我的目标是获得以下情节:
目标
\begin{tikzpicture}[]
\begin{axis}[
grid=both,
width=7cm, height=7cm,
axis x line=middle,
axis y line=middle,
samples=100,
ymin=-6.2, ymax=6.2,
xmin=-6.2, xmax=6.2,
domain=-6:6,
xlabel=$x$,
ylabel={$y$},
axis equal image
]
\addplot[blue,line width=1pt,rounded corners=1pt] coordinates {
(-6,4)
(-2,0)
(-1,0)
(0,-3)
(1,1)
(2,0)
(3,1)
} node[right]{$f(x)$};
\addplot[red,line width=1pt,rounded corners=1pt] coordinates {
(-6,{2^4})
(-2,{2^0})
(-1,{2^0})
(0,{2^(-10)})
(1,{2^1})
(2,{2^0})
(3,{2^1})
} node[right]{$2^{f(x)}$};
\end{axis}
\end{tikzpicture}
答案1
这是构建分段图的一种方法Asymptote
:
//
// "gpiecewise.asy"
//
// run
// asy gpiecewise.asy
//
// to get a standalone
// "gpiecewise.pdf"
//
settings.tex="pdflatex";
import graph;
import math;
import fontsize;defaultpen(fontsize(8pt));
texpreamble("\usepackage{lmodern}"+"\usepackage{amsmath}"
+"\usepackage{amsfonts}"+"\usepackage{amssymb}");
pen linePen =darkblue+ .8bp;
pen line2Pen=orange+ .8bp;
pen grayPen =gray(0.3)+0.5bp;
real scx=0.25, scy=1;
int xCells=38, yCells=22;
add(shift(-25*scx,-5*scy)*scale(scx,scy)*grid(xCells,yCells,paleblue+0.2bp));
real pagew=9cm,pageh=yCells/xCells*9cm;
size(pagew,pageh,IgnoreAspect);
real xmin=-6,xmax=3;
real ymin=-4,ymax=16;
xaxis(xmin,xmax,RightTicks(Step=1,step=0.5,OmitTick(0)),above=true,p=grayPen);
yaxis(ymin,ymax,LeftTicks (Step=2,step=1, OmitTick(0)),above=true,p=grayPen);
pair[]p ={(-6, 4),(-2, 0),(-1, 0),( 0,-3),( 1, 1),( 2, 0),( 3, 1),};
real[]px=map(xpart, p);
real[]py=map(ypart, p);
real fl(real x, pair a, pair b){
return a.y*(1-(x-a.x)/(b.x-a.x))+b.y*(x-a.x)/(b.x-a.x);
}
pair f(real x){
int k=search(px,x);
return (x,fl(x,p[k],p[k+1]));
}
pair f2(real x){
int k=search(px,x);
return (x,2^fl(x,p[k],p[k+1]));
}
real eps=1e-7;
draw(graph(f, xmin,xmax-eps,200),linePen);
draw(graph(f2,xmin,xmax-eps,200),line2Pen);
label("$f(x)$",f(-5.5) ,plain.NE);
label("$2^{f(x)}$",f2(-5.5),plain.NE);
如果你确实需要TikZ
代码,你可以使用以下方法将asy
源转换为.svg
输出
asy -f svg gpiecewise.asy
然后将其转换为 TikZsvg2tikz:
svg2tikz --standalone gpiecewise.svg > gpiecewise.tex
并获取gpiecewise.tex
带有代码的文件TikZ
。
答案2
完整的 PGF-TikZ 解决方案
pgfplots
我正在寻找完整的 PGF-TikZ 解决方案。我通过以下想法以及和包的帮助找到了它pgfplotstable
。
A(a1,a2)
和之间的直线函数B(b1,b2)
定义为(g.kov 的回答) 经过
f(x)=(x-a1)/(a2-a1)*(b2-b1)+b2
要“逐块”绘制合成函数
g(f(x))
(此处g(x)=2^x
)。这意味着n点/坐标n-1每个部分都有域\xstart:\xend
\addplot[domain=\xstart:\xend,mark=none,smooth, red] {2^((x-\xstart)/(\xend-\xstart)*(\yend-\ystart)+\ystart))};
获取要绘制的值
\pgfplotstablegetelem{<row>}{<column name>}
里面
\addplot
。通过循环绘制所有部分,这样可以同时访问数据表的两行。可以通过添加第二个计数器来实现这
\points
一点。\points
\second
\foreach \piece[count=\second] in {0,...,\numberofrows}
通过检查计数器来停止情节循环
\numberofrows
。\pgfplotstablegetrowsof{\points} \pgfmathtruncatemacro{\numberofrows}{\pgfplotsretval-2}
foreach
请注意,在内部读取表格可能会很困难axis
。此外,pgfplotstable
手册建议避免使用\pgfplotstablegetelem
内部循环(第 62 页)。无论如何,我的代码似乎足够快。欢迎任何有建议或可以改进代码的人。
代码
\documentclass[]{standalone}
\usepackage{pgfplots,pgfplotstable}
\begin{document}
% An arbitrary set of points
\pgfplotstableread[col sep=comma]{
X,Y
-6,4
-3,0
-1,0
0,-3
2,1
4,0
5,1
}\points
% The (integer) number of points
\pgfplotstablegetrowsof{\points}
\pgfmathtruncatemacro{\numberofrows}{\pgfplotsretval-2}
\begin{tikzpicture}[]
\pgfplotsset{table/col sep = comma}
\begin{axis}[
width=7cm, height=7cm,
axis x line=middle,
axis y line=middle,
samples=100,
ymin=-3.2, ymax=4.2,
xmin=-6.2, xmax=6.5,
domain=-6:6,
xlabel=$x$,
ylabel={$y$},
]
% the original piecewise function f
\addplot[blue,mark=none] table[x=X,y=Y] from \points;
% the composition function g(f(x))=2^x
\foreach \piece[count=\second] in {0,...,\numberofrows}
{
% set the needed values
\pgfplotstablegetelem{\piece}{X}\of\points
\pgfmathsetmacro{\xstart}{\pgfplotsretval}
\pgfplotstablegetelem{\piece}{Y}\of\points
\pgfmathsetmacro{\ystart}{\pgfplotsretval}
\pgfplotstablegetelem{\second}{X}\of\points
\pgfmathsetmacro{\xend}{\pgfplotsretval}
\pgfplotstablegetelem{\second}{Y}\of\points
\pgfmathsetmacro{\yend}{\pgfplotsretval}
% plot the piece g(f(x))
\addplot[domain=\xstart:\xend,mark=none,smooth, red]
{2^((x-\xstart)/(\xend-\xstart)*(\yend-\ystart)+\ystart)};
}
\end{axis}
\end{tikzpicture}
\end{document}
输出
另一篇有趣的作品
% a second composition for fun with g(x)=2*sin(x)
\foreach \piece[count=\second] in {0,...,\numberofrows}
{
% set the needed values
\pgfplotstablegetelem{\piece}{X}\of\points
\pgfmathsetmacro{\xstart}{\pgfplotsretval}
\pgfplotstablegetelem{\piece}{Y}\of\points
\pgfmathsetmacro{\ystart}{\pgfplotsretval}
\pgfplotstablegetelem{\second}{X}\of\points
\pgfmathsetmacro{\xend}{\pgfplotsretval}
\pgfplotstablegetelem{\second}{Y}\of\points
\pgfmathsetmacro{\yend}{\pgfplotsretval}
% plot the piece g(f(x))
\addplot[domain=\xstart:\xend,mark=none,smooth, orange]
{2*sin(deg((x-\xstart)/(\xend-\xstart)*(\yend-\ystart)+\ystart))};
}