我在绘制该图时遇到了一个奇怪的渲染问题,其中填充区域似乎离开了它所界定的区域。
只是想知道是否有其他人能够重现此错误/建议修复。
知道如果我使用const plot mark right
这个问题就会消失,但图形的外观不正确,这可能会有所帮助。
我的 MWE 如下:
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepgfplotslibrary{fillbetween}
% Define custom colors
\definecolor{CustomBlue}{rgb}{0.05882, 0.3725, 0.8392} % #0F95D7
\definecolor{CustomRed}{rgb}{0.8627, 0.1961, 0.1255} % #DC321F
\definecolor{CustomYellow}{rgb}{1, 0.7608, 0.0392} % #FFC20A
% Define default line width as a length
\newlength{\defaultlinewidth}
\setlength{\defaultlinewidth}{1pt}
% Apply default line width in PGFPlots
\pgfplotsset{
every axis plot/.append style={line width=\defaultlinewidth},
every axis plot post/.append style={
every mark/.append style={mark=*, mark size=1.2pt}
}
}
\begin{document}
\newcommand{\xmin}{0.382} % finding x for y = 5
\newcommand{\xmax}{4.25}
\newcommand{\ymax}{5}
\newcommand{\ymin}{0.098765} % finding y for x = 4.25
% Legend settings
\pgfplotsset{every axis legend/.append style={
at={(0.5,-0.05)},
anchor=north}}
\begin{tikzpicture}
\begin{axis}[
width=9cm,
height=8cm,
ticks=none,
axis lines=middle,
xlabel={$f_1$},
ylabel={$f_2$},
xlabel style={anchor=north}, % Move x-axis label below
ylabel style={anchor=east}, % Adjust y-axis label position if needed
xmin=-0.25, xmax=4.35,
ymin=-0.25, ymax=5.25,
domain=0:\xmax,
restrict y to domain=-0.25:\ymax,
samples=1000,
unbounded coords=jump,
]
% Pareto Front.
\addplot+[no marks, color=CustomRed] {2/(x+0.25)^2};
% Place the reference point and show connection to PF
\addplot+[only marks, mark=*, mark options={fill=red, scale=1.5}] coordinates {(\xmax,\ymax)};
\addplot[dashed] (\xmin, \ymax) -- (\xmax,\ymax); % horizontal
\addplot[dashed] (\xmax, \ymax) -- (\xmax,\ymin); % vertical
% Nearest front
\addplot+[name path = badfront, const plot mark left, color=CustomBlue, mark options={fill=CustomBlue}, samples at={1.025, 1.22, 1.35, 1.5, 1.75, 2.0, 3, 3.6}] {2.5/(x-0.5)};
% Calculate the y-value for the last mark
\pgfmathsetmacro{\lastMarkYValue}{2.5/(3.6-0.5)}
% Draw the last mark
\addplot+[only marks, color=CustomBlue, mark options={fill=CustomBlue}] coordinates {(3.6,\lastMarkYValue)};
% Draw a line from the last mark to the new point
% Repeat the above but for the first mark.
\pgfmathsetmacro{\firstMarkYValue}{2.5/(1.025-0.5)}
\addplot+[only marks, color=CustomBlue, mark options={fill=CustomBlue}] coordinates {(3.6,\lastMarkYValue)};
% Shade the hypervolume
% Path defining the curve.
\addplot[name path = hvcurve, color=CustomRed] (1.025,\firstMarkYValue) -- (1.025,\ymax) -- ( \xmax, \ymax) -- ( \xmax, \lastMarkYValue) -- (3.6,\lastMarkYValue);
% Fill between the const plot and the upper line
\addplot fill between[of=badfront and hvcurve,
every segment no 0/.style={fill, color=CustomBlue!20}, area legend]; % Adjust the segment number as needed
% Single point to display HV improvement
\newcommand{\hvimpX}{2.6}
\newcommand{\hvimpY}{1.25}
\addplot+[only marks, color=CustomYellow, mark options={fill=CustomYellow}] coordinates {(\hvimpX,\hvimpY)};
% Shade HV improvement
\pgfmathsetmacro{\hvimpFrontY}{2.5/(2.0-0.5)}
\pgfmathsetmacro{\hvimpFrontX}{3}
\addplot[name path = hvimpcurve, color=CustomYellow, fill=CustomYellow!20] (\hvimpX,\hvimpY) -- (\hvimpX,\hvimpFrontY) -- ( \hvimpFrontX, \hvimpFrontY) -- ( \hvimpFrontX, \hvimpY) -- cycle;
\end{axis}
\end{tikzpicture}
\end{document}
在此先感谢您的任何建议。
答案1
问题出在hvcurve
曲线的定义上,它从点开始(1.025,firstMarkYValue)
,到点结束(3.6,lastMarkYValue)
。只需反转此路径即可使填充正确。正确的路径是这样的:
%% Path defining the curve.
\addplot[name path = hvcurve, color=CustomRed] (3.6,\lastMarkYValue) -| ( \xmax, \ymax) -|(1.025,\firstMarkYValue) ;
完整代码
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.13}
\usepgfplotslibrary{fillbetween}
% Define custom colors
\definecolor{CustomBlue}{rgb}{0.05882, 0.3725, 0.8392} % #0F95D7
\definecolor{CustomRed}{rgb}{0.8627, 0.1961, 0.1255} % #DC321F
\definecolor{CustomYellow}{rgb}{1, 0.7608, 0.0392} % #FFC20A
% Define default line width as a length
\newlength{\defaultlinewidth}
\setlength{\defaultlinewidth}{1pt}
% Apply default line width in PGFPlots
\pgfplotsset{
every axis plot/.append style={line width=\defaultlinewidth},
every axis plot post/.append style={
every mark/.append style={mark=*, mark size=1.2pt}
}
}
\begin{document}
\newcommand{\xmin}{0.382} % finding x for y = 5
\newcommand{\xmax}{4.25}
\newcommand{\ymax}{5}
\newcommand{\ymin}{0.098765} % finding y for x = 4.25
% Legend settings
\pgfplotsset{every axis legend/.append style={
at={(0.5,-0.05)},
anchor=north}}
\begin{tikzpicture}
\begin{axis}[
width=9cm,
height=8cm,
ticks=none,
axis lines=middle,
xlabel={$f_1$},
ylabel={$f_2$},
xlabel style={anchor=north}, % Move x-axis label below
ylabel style={anchor=east}, % Adjust y-axis label position if needed
xmin=-0.25, xmax=4.35,
ymin=-0.25, ymax=5.25,
domain=0:\xmax,
restrict y to domain=-0.25:\ymax,
samples=1000,
unbounded coords=jump,
]
% Pareto Front.
\addplot+[no marks, color=CustomRed] {2/(x+0.25)^2};
Place the reference point and show connection to PF
\addplot+[only marks, mark=*, mark options={fill=red, scale=1.5}] coordinates {(\xmax,\ymax)};
\addplot[dashed] (\xmin, \ymax) -- (\xmax,\ymax); % horizontal
\addplot[dashed] (\xmax, \ymax) -- (\xmax,\ymin); % vertical
%
% Nearest front
\addplot+[name path = badfront, const plot mark left, color=CustomBlue, mark options={fill=CustomBlue}, samples at={1.025, 1.22, 1.35, 1.5, 1.75, 2.0, 3, 3.6}] {2.5/(x-0.5)};
% Calculate the y-value for the last mark
\pgfmathsetmacro{\lastMarkYValue}{2.5/(3.6-0.5)}
%% Draw the last mark
\addplot+[only marks, color=CustomBlue, mark options={fill=CustomBlue}] coordinates {(3.6,\lastMarkYValue)};
% Draw a line from the last mark to the new point
% Repeat the above but for the first mark.
\pgfmathsetmacro{\firstMarkYValue}{2.5/(1.025-0.5)}
\addplot+[only marks, color=CustomBlue, mark options={fill=CustomBlue}] coordinates {(3.6,\lastMarkYValue)};
%% Shade the hypervolume
%% Path defining the curve.
\addplot[name path = hvcurve, color=CustomRed] (3.6,\lastMarkYValue) -| ( \xmax, \ymax) -|(1.025,\firstMarkYValue) ;
% Fill between the const plot and the upper line
\addplot fill between[of=badfront and hvcurve,
every segment no 0/.style={fill, color=CustomBlue!20}, area legend]; % Adjust the segment number as needed
% Single point to display HV improvement
\newcommand{\hvimpX}{2.6}
\newcommand{\hvimpY}{1.25}
\addplot+[only marks, color=CustomYellow, mark options={fill=CustomYellow}] coordinates {(\hvimpX,\hvimpY)};
% Shade HV improvement
\pgfmathsetmacro{\hvimpFrontY}{2.5/(2.0-0.5)}
\pgfmathsetmacro{\hvimpFrontX}{3}
\addplot[name path = hvimpcurve, color=CustomYellow, fill=CustomYellow!20,fill opacity=.5] (\hvimpX,\hvimpY) -- (\hvimpX,\hvimpFrontY) -- ( \hvimpFrontX, \hvimpFrontY) -- ( \hvimpFrontX, \hvimpY) -- cycle;
\end{axis}
\end{tikzpicture}
\end{document}
答案2
像这样:
代码(非常短):
\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw[-latex] (-1,0)--(8,0) node[below] () {$f_1$};
\draw[-latex] (0,-1)--(0,8) node[left] () {$f_2$};
\draw[red,line width=3pt] plot[domain=.25:7.6,smooth,samples=103] (\x,{2/\x});
\draw[blue,line width=3pt] plot[domain=.25:7.6] (\x,8);
\shadedraw[top color=cyan,bottom color=blue,draw=none,opacity=.5] (.25,8) -- plot [domain=.25:7.6] (\x,{2/\x}) -- plot [domain=7.6:.25] (\x,8)-- cycle;
\end{tikzpicture}
\end{document}