pgfplot 라인을 최대 기능 이하로 자동으로 점선으로 표시합니다.

pgfplot 라인을 최대 기능 이하로 자동으로 점선으로 표시합니다.

max아래 최소 작업 예제에 표시된 PWLF(조각 선형 함수)를 최대값으로 만드는 선형 함수를 표시하는 그래프를 만들고 싶습니다 . 현재 최대값을 강조하기 위해 max()를 호출하고 인수로 선형 함수를 사용하고 다른 플롯을 두꺼운 검정색으로 오버레이하여 PWLF를 표시하는 플롯을 추가하고 있습니다. 기여 함수는 특정 지역에서 "기여하지 않음"을 강조하기 위해 수동으로 점선으로 그려집니다.

실제로 내가 원하는 것은 플롯의 해당 세그먼트를 구성하는 선형 함수에 대한 색상 정보를 PWLF에 유지하기 위해 모든 선이 최대값의 일부가 아닌 경우 점선으로 표시하고 그렇지 않으면 실선으로 표시하는 것입니다.

이상적으로는 선분을 수동으로 그릴 필요 없이 이를 설명적으로 수행할 수 있는 방법이 있습니까? 각 예제의 교차점을 계산한 다음 매번 적절한 플롯을 생성할 필요가 정말 없습니다.

MWE는 현재 다음 출력을 생성합니다.

여기에 이미지 설명을 입력하세요

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}

Colcalc의 출력은 다음과 같습니다. 여기에 이미지 설명을 입력하세요 자세히 보기: 여기에 이미지 설명을 입력하세요

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에 추가됩니다. 선이 최대값을 달성하는 x 값이 1개만 있는 경우(예: 같은 점에서 교차하는 3개의 선)가 있을 수 있습니다. 이 경우에는 이를 플롯하지 않습니다. 실제로 max 함수의 일부인 모든 라인에는 최대값을 달성하는 지점이 두 개 이상 있습니다. 따라서 f1에 두 개 이상의 점이 있다고 가정하면 if len(f1x)>1:선으로 확인된 내용이 max 함수의 일부로 표시됩니다.

관련 정보