我想使用 构建几个帕累托图\newcommand
,如下所示:
\documentclass[11pt]{amsart}
\usepackage{pgfplots}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{xfp}
\definecolor{Azul}{rgb}{0.16, 0.32, 0.75}
\newcommand{\GraficoPareto}[9]{
\begin{tikzpicture}
\draw (0,0) rectangle (10,5);
\foreach \i/\j in {0/#6,2/#7,4/#8,6/#9,8/,10/}{
\draw (\i,2pt) -- (\i,-2pt) node[below] { \j };
}
\foreach \i in {0,1,...,5}{
\ifnum\i>0
\draw[densely dashed,gray] (-.1,\i) -- (10.1,\i) node[right] {\textcolor{black}{$\fpeval{20*\i}\%$}};
\else
\node[right,gray] (Texto) at (10.1,\i) {\textcolor{black}{$\fpeval{20*\i}\%$}};
\fi
\node[left] (Te) at (-0.1,\i) {$\fpeval{8*\i}$};
}
\fill[Azul!100!black,opacity=0.8] (0.02,0) rectangle ({2-0.02},{#1*5/40});
\fill[Azul!100!black,opacity=0.8] (2.02,0) rectangle ({4-0.02},{#2*5/40});
\fill[Azul!100!black,opacity=0.8] (4.02,0) rectangle ({6-0.02},{#3*5/40});
\fill[Azul!100!black,opacity=0.8] (6.02,0) rectangle ({8-0.02},{#4*5/40});
\fill[Azul!100!black,opacity=0.8] (8.02,0) rectangle ({10-0.02},{#5*5/40});
\draw[line width=3pt,orange] (1,{5*(#1/50)}) -- (3,{5*((#1+#2)/50)}) -- (5,{5*((#1+#2+#3)/50)}) -- (7,{5*((#1+#2+#3+#4)/50)}) -- (9,{5*((#1+#2+#3+#4+#5)/50)});
\node (Legendax) at (5,-1) {Soma das horas};
\node (Legenday) at (-1,2.5) {\rotatebox{90}{Frequência}};
\end{tikzpicture}
}
\begin{document}
\GraficoPareto{30}{10}{5}{3}{2}{94}{194}{294}{394}
\end{document}
这是谁的结果:
但是,我想插入另外两个参数(然后是 11),以便定义最终的 x 标签。但这行不通。
我如何使用 11 个参数来定义这个图形?
答案1
newcommand
我建议采用基于列表的方法。这个答案是其中的一部分。这个想法是尽可能广泛地使用语法的单一输入。你的原始想法不可扩展(你不能根据需要添加更多的输入),这是一个重大缺陷,因为我可能猜您想要扩展(扩大)以容纳更多数据。
这个答案基于:
- LaTeX 中的帕累托图
- 用 pgfplots 绘制帕累托图?
- https://www.ctan.org/pkg/pgfplots
- pgfplots:一个数据集有两个轴,例如°C 和°F
- 使用 pgfplot 绘制条形之间的距离
我创建了一个newcommand
以两个输入为坐标的
addplot
格式的命令axis
。
我建议你了解一下pgfplots
,这是一个很棒的工具。我不是专家,可能有更好的方法来实现你想要的结果。
请注意,我的答案没有计算频率(频率)而是只显示累计和(积累) 手动插入到第二个输入参数中。不过,还有几个选项:
- 使用任何数学工具或计算机代码为您写下这两个列表;
- 学习如何在 TikZ 中直接进行数学运算(抱歉,我不知道这个坐标技巧);
- 查看链接 4 和 5 中的参考资料,了解如何使用数据或外部文件创建表格。
MWE 是:
\documentclass{article}
\usepackage{pgfplots}
\newcommand{\myPareto}[2]{
\begin{tikzpicture}
\begin{axis}[
ylabel={Acumulado},
xlabel={Soma das horas},
ymin=0,
xtick=data,
axis y line*=left,
ymajorgrids,
major y grid style={dashed, thick}
]
\addplot[ybar interval, fill=blue, opacity=0.5] coordinates {#1};
\addplot[draw, mark=*, orange, ultra thick] coordinates {#2};
\end{axis}
\begin{axis}[
axis y line*=right,
axis x line=none,
yticklabel={\pgfmathparse{100*\tick}\pgfmathprintnumber[fixed,precision=0]\pgfmathresult\%},
ymin=0,
]
\end{axis}
\end{tikzpicture}
}
\begin{document}
\myPareto{(94,30) (194,10) (294,5) (394,3) (494,2) (594,0)}
{(144,30) (244,40) (344,45) (444,48) (544,50)}
\end{document}
我添加了mark=*
显示第二个输入的坐标。结果如下所示。
答案2
我不会构建这样的(怪物)\newcommand
。而是使用表格,其中收集了图表的数据。在我看来,这种方法更清晰、更灵活(您可以简单地用更多行和列来扩展表格)。除此之外,这种 MWE 更容易被其他人理解,最终会对您的代码感兴趣(例如,如果您将它用于期刊文章):
\documentclass[margin=3.141592]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\pgfplotstableread{
X1 y1 X2 y2
94 30 144 30
194 10 244 40
294 5 344 45
394 3 444 48
494 2 544 50
594 0 nan nan
}{\datatable}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
ymajorgrids,
major y grid style={dashed},
ylabel={Acumulado},
xtick=data,
xlabel={Soma das horas},
ymin=0,
]
\addplot [ybar interval, fill=blue, semitransparent]
table [x=X1, y=y1] {\datatable};
\addplot [orange, very thick, mark=*]
table [x=X2, y=y2] {\datatable};
\end{axis}
\begin{axis}[
axis y line*=right,
axis x line=none,
yticklabel={\pgfmathparse{int(round(100*\tick))}%
\pgfmathresult\%
},
ymin=0,
]
\end{axis}
\end{tikzpicture}
\end{document}