我将以下 pgfplots 图表嵌入到 TeX 文档中,对此我非常满意。最近,我在阅读 metapost 时,想尝试使用它重新创建图表。
\begin{figure}[ht]
\centering
\begin{tikzpicture}
\begin{axis}[
width = \textwidth,
height = 1.1\textwidth,
xlabel = Days,
ylabel = kg,
xmin = 0,
xmax = 450,
ymin = 2,
grid = both,
minor x tick num = 1,
minor y tick num = 3,
]
\addplot[red, mark=*] table [x=Days, y expr=\thisrow{Weight}/1000] {weight.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P01] {wfa_boys_p_exp.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P1] {wfa_boys_p_exp.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P3] {wfa_boys_p_exp.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P5] {wfa_boys_p_exp.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P10] {wfa_boys_p_exp.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P15] {wfa_boys_p_exp.txt};
\addplot[gray, restrict x to domain=0:450] table [x=Age, y=P25] {wfa_boys_p_exp.txt};
\end{axis}
\end{tikzpicture}
\end{figure}
我使用了这个图表中的许多功能,想知道 metapost 是否支持这些功能。例如,将 x 值限制为一个域,使用值的表达式,x/y 最小值/最大值等。
是否可以使用相同的数据文件在 metapost 中重新创建这样的图表?
答案1
这是使用 Python 读取 OP 数据文件并为 Metapost 生成输入而生成的图表。
这是 Python 源代码。我使用了 Python3 语法。使用方法如下:
用合适的名字保存 Python 源代码
growth_chart.py
将 OP 数据文件保存在
weight.txt
与wfa_boys_p_exp.txt
python3 growth_chart.py > temp.mp && mpost temp
在命令行上运行如果运行没有错误,Metapost 将生成
temp1.eps
您可以包含在 LaTex 中、或使用 PostScript 查看器打开、或使用convert
、或ps2pdf
、或 OSX Preview 等转换为 PDF 的内容...
我并没有尝试让它完全通用,例如 450 天和每公斤 40 个点的 y 缩放只是硬编码的。如果你试图让它太通用,你最终可能会重写整个 pgfplots。
weight_path = list()
with open('weight.txt', 'rt') as w:
for line in w:
date, days, weight, change = line.split()
if date == 'Date':
continue
weight_path.append( (int(days), int(weight)/1000) )
P01_path = list()
P1_path = list()
P3_path = list()
P5_path = list()
P10_path = list()
P15_path = list()
P25_path = list()
with open('wfa_boys_p_exp.txt', 'rt') as p:
for line in p:
Age, L, M, S, P01, P1, P3, P5, P10, P15, P25, P50, P75, P85, P90, P95, P97, P99, P999 = line.split()
if Age == 'Age':
continue
if Age == '450':
break
P01_path.append( (int(Age), float(P01)) )
P1_path.append( (int(Age), float(P1)) )
P3_path.append( (int(Age), float(P3)) )
P5_path.append( (int(Age), float(P5)) )
P10_path.append( (int(Age), float(P10)) )
P15_path.append( (int(Age), float(P15)) )
P25_path.append( (int(Age), float(P25)) )
print('''
prologues := 3;
outputtemplate := "%j%c.eps";
defaultfont := "phvr8r";
beginfig(1);
''')
print('path w, p[];')
print('w = ({}) yscaled 40;'.format('--'.join(str(x) for x in weight_path)))
print('p0 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P01_path)))
print('p1 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P1_path)))
print('p2 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P3_path)))
print('p3 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P5_path)))
print('p4 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P10_path)))
print('p5 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P15_path)))
print('p6 = ({}) yscaled 40;'.format('--'.join(str(x) for x in P25_path)))
print('''
path xx, yy;
xx = origin -- (456, 0);
yy = origin -- (0, 406);
for x = 30 step 30 until 450:
draw yy shifted (x,0) withcolor .9 white;
label.bot(decimal x, (x,0));
endfor
for y = 1 upto 10:
draw xx shifted (0,40y) withcolor .9 white;
label.lft(decimal y, (0,40y));
endfor
drawarrow xx; label.rt("Days", point infinity of xx);
drawarrow yy; label.top("Weight (kg)", point infinity of yy);
''')
print('''
draw p0 withcolor .40[blue,white]; label.rt("0.1%" infont defaultfont scaled 0.8, point infinity of p0);
draw p1 withcolor .45[blue,white]; label.rt("1%" infont defaultfont scaled 0.8, point infinity of p1);
draw p2 withcolor .50[blue,white]; label.rt("3%" infont defaultfont scaled 0.8, point infinity of p2);
draw p3 withcolor .55[blue,white]; label.rt("5%" infont defaultfont scaled 0.8, point infinity of p3);
draw p4 withcolor .60[blue,white]; label.rt("10%" infont defaultfont scaled 0.8, point infinity of p4);
draw p5 withcolor .65[blue,white]; label.rt("15%" infont defaultfont scaled 0.8, point infinity of p5);
draw p6 withcolor .70[blue,white]; label.rt("25%" infont defaultfont scaled 0.8, point infinity of p6);
draw w withcolor .67 red;
for i=0 upto length w:
unfill fullcircle scaled 4 shifted point i of w;
fill fullcircle scaled 2 shifted point i of w;
endfor
''')
print('''
endfig;end.
''')