我想创建一个图表,显示线性函数,其最大值构建分段线性函数 (PWLF),如max
下面的最小工作示例中所示。目前,为了突出显示最大值,我添加了一个绘图,该绘图调用 max() 并作为参数,以线性函数为参数,并覆盖另一个粗黑色绘图以显示 PWLF。贡献函数手动绘制为虚线,以突出显示它们在某些区域“不贡献”的事实。
实际上,我想要做的是,如果所有线不是最大值的一部分,则将它们变为虚线,否则变为实线,以保留 PWLF 中的颜色信息,以表明哪个线性函数构成了该图段。
有没有办法以描述的方式做到这一点,理想情况下无需手动绘制线段?我真的不想每次都计算每个示例的交点,然后创建适当的图。
MWE 当前生成以下输出:
梅威瑟:
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{positioning}
\usepackage{amsmath}
\pgfplotsset{
legend entry/.initial=,
every axis plot post/.code={%
\pgfkeysgetvalue{/pgfplots/legend entry}\tempValue
\ifx\tempValue\empty
\pgfkeysalso{/pgfplots/forget plot}%
\else
\expandafter\addlegendentry\expandafter{\tempValue}%
\fi
},
}
\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}
\begin{axis}[width=\textwidth, enlargelimits=false, legend pos=outer north east, ytick=\empty, xtick={0, 1}, %
xticklabels={1 - $S_0$, $S_0$}]
\addplot[blue, dashed, thick, no marks, domain=0:1, legend entry=$a_1$]%
({x},{0.8 - 0.5*x});%
\addplot[olive, thick, dashed, no marks, domain=0:1, legend entry=$a_2$]%
({x}, {0.6 - 0.2*x});%
\addplot [red, thick, dashed, no marks, domain=0:1, legend entry=$a_3$]%
({x}, {0.3+0.4*x});%
\addplot [orange, dashed, thick, no marks, domain=0:1, legend entry=$a_4$]%
({x}, {0.5+0.1*x});%
\addplot [black, ultra thick, no marks, domain=0:1, legend entry=$\text{max}$] {max(0.8-0.5*x,0.3+0.4*x, 0.5+0.1*x)};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
答案1
这sagetex
软件包可以处理这个问题。它的文档位于 CTAN这里。这样你就可以将工作外包给计算机代数系统 SAGE,它的网站这里。这意味着你需要下载 SAGE 到你的电脑并正确安装它,或者打开一个免费的可钙帐户。如果您有 Cocalc 帐户,只需粘贴创建一个 LaTeX 文档,将下面的代码复制/粘贴到您的文档中,保存它,然后按构建即可查看结果。编辑:我修改了代码以修复图例中的错误,并使其看起来更像 OP 发布的情节。将 max 函数放入图例中会使其变为纯蓝色,因此我将其删除。
\documentclass[border=4pt]{standalone}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\begin{document}
\begin{sagesilent}
f1 = 0.8-0.5*x
f2 = 0.6-0.2*x
f3 = 0.3+0.4*x
f4 = 0.5+0.1*x
t = var('t')
LowerY = 0.0
UpperY = 1.0
LowerX = 0.0
UpperX = 1.0
step = .001
f1x = [t for t in srange(LowerX,UpperX,step) if f1(t)==max(f1(t),f2(t),f3(t),f4(t))]
f1y = [f1(t) for t in f1x]
f2x = [t for t in srange(LowerX,UpperX,step) if f2(t)==max(f1(t),f2(t),f3(t),f4(t))]
f2y = [f2(t) for t in f2x]
f3x = [t for t in srange(LowerX,UpperX,step) if f3(t)==max(f1(t),f2(t),f3(t),f4(t))]
f3y = [f3(t) for t in f3x]
f4x = [t for t in srange(LowerX,UpperX,step) if f4(t)==max(f1(t),f2(t),f3(t),f4(t))]
f4y = [f4(t) for t in f4x]
output = r""
output += r"\begin{tikzpicture}[scale=.7]"
output += r"\begin{axis}[width=\textwidth, enlargelimits=false, legend pos=outer north east, ytick=\empty, xtick={0, 1}, xticklabels={1-$S_0$,$S_0$}]"
output += r"\addplot[blue, dashed, thick, no marks, domain=0:1]"
output += r"({x},{0.8 - 0.5*x});"
output += r"\addlegendentry{$f1$}"
output += r"\addplot[olive, thick, dashed, no marks, domain=0:1]"
output += r"({x}, {0.6 - 0.2*x});"
output += r"\addlegendentry{$f2$}"
output += r"\addplot [red, thick, dashed, no marks, domain=0:1]"
output += r"({x}, {0.3+0.4*x});"
output += r"\addlegendentry{$f3$}"
output += r"\addplot [orange, dashed, thick, no marks, domain=0:1]"
output += r"({x}, {0.5+0.1*x});"
output += r"\addlegendentry{$a4$}"
if len(f1x)>1:
output += r"\addplot[blue,thick] coordinates {"
for i in range(0,len(f1x)-1):
output += r"(%f,%f) "%(f1x[i],f1y[i])
output += r"};"
if len(f2x)>1:
output += r"\addplot[olive,thick] coordinates {"
for i in range(0,len(f2x)-1):
output += r"(%f,%f) "%(f2x[i],f2y[i])
output += r"};"
if len(f3x)>1:
output += r"\addplot[red,thick] coordinates {"
for i in range(0,len(f3x)-1):
output += r"(%f,%f) "%(f3x[i],f3y[i])
output += r"};"
if len(f4x)>1:
output += r"\addplot[orange,thick] coordinates {"
for i in range(0,len(f4x)-1):
output += r"(%f,%f) "%(f4x[i],f4y[i])
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\sagestr{output}
\end{document}
Python 是 SAGE 中使用的语言。将 4 条线定义为 f1 到 f4 后,代码
f1x = [t for t in srange(LowerX,UpperX,step) if f1(t)==max(f1(t),f2(t),f3(t),f4(t))] f1y = [f1(t) for t in f1x]
将为线 f1 创建 x 和 y 坐标列表。如果 f1 是所有 4 条线上的最大点,则将一个点添加到 f1x,在这种情况下,y 值将添加到 f1y。可能存在这样的情况(例如 3 条线在同一点相交),即只有 1 个 x 值使线达到最大值,在这种情况下我们不绘制该值;任何真正属于 max 函数的线至少有两个点可达到最大值。因此,假设 f1 中有多个点,则if len(f1x)>1:
该线的检查结果将作为 max 函数的一部分绘制。