使用 Tikz 自定义栏

使用 Tikz 自定义栏

我想画一个这样的条形图:

\documentclass[convert = false, border=1cm]{standalone}
\usepackage{tikz,pgfplots}
\usepackage{ifthen}

\begin{document}

\begin{tikzpicture}
    
    \newcommand{\dist}{0.025\linewidth}

    \newcommand{\swr}[5]{% 1:x1 2:y1 3:x2 4:y2 5:percent
        \pgfmathsetmacro \val {#1+#5*(#3-#1)};
        \fill[gray] (#1,#2) rectangle (\val,#4);
        \draw[very thick] (#1,#2) rectangle (#3,#4);
        \foreach \i in {1,...,4} {
            \pgfmathsetmacro \x {#1+(\i-1)*(#3-#1)/3};
            \node at (\x,#2-\dist) {\ifthenelse{\i=4}{$\infty$}{\i}};
        }
    }

    \swr{1}{0}{5}{1}{0.5};

\end{tikzpicture}

\end{document}

预期的

但是,如果我使用相对于线宽的相对放置,则一切都会中断:

\swr{0.1\linewidth}{0.55\linewidth}{0.5\linewidth}{0.55\linewidth+\dist}{0.5};

在此处输入图片描述

知道我做错了什么吗?

答案1

例子

我修改了你的命令,试图使参数同质化。

  • 名字是\mswr

  • 它有一个可选参数(第一个),用于确定其他 5 个参数的缩放比例。如果它为空,则缩放比例为 1。我认为这样使用更容易。

  • 我通过分别将参数 3 和 4 连接到参数 1 和 2 来更改定义中的参数 3 和 4。这样我就可以摆脱\dist定义中的变量。

评论我真的搞不清楚你想在什么情况下使用你的命令。它会成为更大图形的一部分,还是会单独用于文本段落中?在前一种情况下,我认为定义可能会有所改进...例如,没有前两个强制参数,并且,可能是一个品味问题,将其作为元素pic而不是\newcommand

代码

\documentclass[11pt, a4paper]{article} % [convert = false, border=1cm]{standalone}
\usepackage{tikz}  % pgfplots
\usetikzlibrary{math}
\usepackage{ifthen}
\usepackage{lipsum}
\begin{document}

    
\newcommand{\dist}{0.025\linewidth}
\newcommand{\swr}[5]{% 1:x1 2:y1 3:x2 4:y2 5:percent
  \pgfmathsetmacro{\val}{#1+#5*(#3-#1)};
  \fill[gray] (#1,#2) rectangle (\val,#4);
  \draw[very thick] (#1,#2) rectangle (#3,#4);
  \foreach \i in {1,...,4} {
    \pgfmathsetmacro{\x}{#1+(\i-1)*(#3-#1)/3};
    \node at (\x,#2-\dist) {\ifthenelse{\i=4}{$\infty$}{\i}};
  }
}

\newcommand{\mswr}[7][]{%
  % 1:thales (1 if empty) 2:x1 3:y1 4:x2-x1 5:y2-y1 6:percent
  \ifthenelse{\equal{#1}{}}{\tikzmath{\c = 1cm/1pt;}}{\tikzmath{\c = #1;}}
  \tikzmath{%
    integer \i;
    {%
      \fill[blue!40] (#2*\c pt, #3*\c pt) rectangle ++(#6*#4*\c pt, #5*\c pt);
      \draw[blue, very thick] (#2*\c pt, #3*\c pt) rectangle ++(#4*\c pt, #5*\c pt);
    };
    for \i in {1, ..., 4}{%
      \x = #2*\c +(\i -1)*#4*\c/3;
      if \i<4 then {%
        {%
          \path (\x pt, #3*\c pt) node[below, minimum height=3.1ex] {$\i$};
        };
      } else {%
        {%
          \path (\x pt, #3*\c pt) node[below, minimum height=3.1ex] {$\infty$};
        };        
      };
    };
  }
}

\setlength{\parindent}{0pt}
\section*{The modified command is in blue}

There is no difference if the arguments are numbers.

\bigskip
\begin{tikzpicture}
  \swr{1}{0}{5}{1}{0.5};
  \mswr{1}{-2}{4}{1}{0.5};  
\end{tikzpicture}


Below, the arguments are relative quantities with respect to \verb|\linewidth|.

\bigskip
\begin{tikzpicture}
  \draw (0, 0) grid (7, 4);
  \filldraw (7, 0) circle (2pt) node[below right] {$(7, 0)$};

  \swr{0.1\linewidth}{0.05\linewidth}{0.5\linewidth}{0.05\linewidth+\dist}{0.5};
  \mswr[\linewidth]{.1}{.2}{.4}{.025}{.5};
\end{tikzpicture}

\end{document}

相关内容