因此我需要在文档中包含一些饼图。由于我使用 Metapost 制作所有图形,因此我尝试使用PiechartMP
Metapost 包。但出于某种奇怪的原因,没有显示任何文本,只有一个非常小的方块。
最小的例子:
\startMPinitializations
input piechartmp ;
\stopMPinitializations
\startreusableMPgraphic{pie}
u := 5mm;
r := 3u;
SetupPercent(this, "x") ;
Segment(32.5,"first",auto);
Segment(12.8,"second",auto);
Segment(22.4,"third",auto);
Segment(18.2,"fourth",auto);
beginfig(1);
PieChart(r, 0, 0, 0, 0);
SetupValue("{\tfd ", "}");
label (btex textext(Text) etex,origin);
endfig;
\stopreusableMPgraphic
\starttext
\reuseMPgraphic{pie}
\stoptext
我尝试过使用TEX
(加载 MetapostTEX
模块)、使用\sometxt
和textext
命令,但都没有成功。在 Metapost 中设置更大或不同的字体只会使该方块变大,但不显示任何文本。我做错了什么吗?提前感谢您的帮助。
答案1
修复方法(简短版本)
您缺少简单的兼容模式:
\starttext
\startMPcode
useplainlabels ;
input piechartmp;
Segment(30, "first");
Segment(70, "second");
PieChart(1cm, 0, 0, 0, 0);
Label.auto(0)(name)(outwards,0);
ResetSegments;
\stopMPcode
\stoptext
失败原因
与传统的 MetaPost 不同,MkIV 使用 LuaTeX 内置的 MetaPost 库 mplib。在 mplib 中,许多 MetaPost 变量被放入
namespace
分离内部代码并减少名称冲突的可能性。通常这没有问题,用户很少直接更改它们。然而,一些 MetaPost 模块(其中包括 PiechartMP 模块)依赖于原始名称,因此与 LuaTeX 不兼容。较新的模块应使用 MetaPost
installlabel
宏以可移植的方式定义标签方向。
这里的关键问题是 PiechartMPauto
使用传统名称定义自定义标签方向,然后 mplib 尝试使用函数的偏移量来排版这些标签
thelabel
计算,其假设命名空间的新名称。
要使 PiechartMP 模块与 mplib 一起工作,您需要普通兼容模式。此模式包含在 ConTeXt 中,因为
2013.08.25 14:06。要切换到兼容模式,请使用宏
useplainlabels
或者对应的环境版本:
startplaincompatibility ;
… some MetaPost code …
stoplaincompatibility ;
针对旧 ConTeXt 版本的解决方案
由于最近才添加了普通兼容模式,并且由于某种原因您无法更新安装,因此您可能需要一种解决方法。最简单的方法是覆盖标签打印功能以使用 PiechartMP 使用的传统名称。缺点是您可以预料到手动排版的标签会损坏。
\startMPinclusions
input piechartmp;
vardef thelabel@#(expr p,z) =
if string p :
thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p)
scaled defaultscale,z)
else :
p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))
enddef;
\stopMPinclusions
\starttext
\startMPcode
Segment(30, "first");
Segment(70, "second");
PieChart(1cm, 0, 0, 0, 0);
Label.auto(0)(name)(outwards,0);
ResetSegments;
\stopMPcode
\stoptext
改善标签排版
您尝试调整饼图中的字体。最好在 MetaPost 实例中进行此类调整,该实例应为这些图表创建。优点是代码是分开的,不会干扰其他 MetaPost 代码。此外,可以使用以下方式自定义 MetaPost 实例
\defineMPinstance
另一个改进是将 MetaPost 标签与 ConTeXt 结合起来,使它们适应正文字体。默认情况下,MetaPost 使用 绘制标签defaultfont
。这是通过将宏挂接
textext
到打印标签的路由中来完成的:
vardef _makeText primary s =
textext(s)
enddef;
下面是一个例子:
\defineMPinstance
[piechartmp] [metafun]
[textstyle=bigbodyfont]
\setupbodyfont [pagella]
\startMPinclusions{piechartmp}
useplainlabels;
input piechartmp;
vardef _makeText primary s =
textext(s)
enddef;
\stopMPinclusions
\starttext
\startMPcode{piechartmp}
SetupPercent(this, "\%");
Segment(38, "first", auto);
Segment(22, "second", auto);
Segment(22, "third" , auto);
Segment(18, "fourth", auto);
PieChart(3cm, 1, 0, 0, .05);
Label.auto(0)(percent)(inwards,(1,1)) withcolor white;
Label.auto(0)(name)(outwards,0);
ResetSegments;
\stopMPcode
\stoptext
由于此实例中使用了较大的字体,因此标签以较大的字体打印
bigbodyfont
,并且它们以 TeXGyre Pagella 打印并适应正文字体。
我替换MPinitializations
为
MPinclusions
原因是 MetaPost 初始化是全球的而不是特定 MetaPost 实例的本地实例。此外,MetaPost 初始化是每张图形都触发,这将比必要的更频繁地执行定义。
重置片段
在每个图表之前或之后,需要使用 重置段
ResetSegments
。如果不重置段,它们会干扰下一个图形,并且会绘制过多的段。这可以手动完成,但重复且容易出错,因此最好将其自动化。如上一节所述,我们认为 MetaPost 初始化是在每个图形。这正是我们想要的。因此让我们自动重置段:
\startMPinitializations
ResetSegments;
\stopMPinitializations
三维图形
默认情况下,PiechartMP 使用统一颜色来绘制三维图表。MetaFun 支持使用linear_shade
宏进行着色。幸运的是,PiechartMP 支持此功能,并且可以在 MetaFun 可用时绘制更逼真的图表。不幸的是,PiechartMP 从特殊扩展代码中检查旧 MkII 变量是否存在,context_spec
而最近的 MkIV 中没有该变量,因此失败了。正确的方法是检查
metafunversion
。认为这是 PiechartMP 中的一个错误。要修复此问题,请定义context_spec
前加载piechartmp.mp
或设置pc_Metafun
为true
,其工作于任何点。这里有两个三维图形,一个使用默认渲染,另一个使用 MetaPost 的线性阴影。
\setupbodyfont [pagella, 16pt]
\startuseMPgraphic{pie-default}
input piechartmp;
Segment(28); Segment(28);
Segment(32); Segment(12);
PieChart(3cm, 1, 65, 0, .0);
ResetSegments;
\stopuseMPgraphic
\startuseMPgraphic{pie-metafun}
pc_Metafun := true;
\includeMPgraphic{pie-default}
\stopuseMPgraphic
\starttext
\startcombination
\startcontent \useMPgraphic{pie-default} \stopcontent
\startcaption Default shading \stopcaption
\startcontent \useMPgraphic{pie-metafun} \stopcontent
\startcaption MetaFun shading \stopcaption
\stopcombination
\stoptext
补充笔记
开始图(1);…结束图;
不要beginfig(1) … endfig
在 MPgraphic 中使用。该图形已定义为
\startuseMPgraphic
或者
\startreusableMPgraphic
。
设置值(“{\tfd”,“}”);
textstyle
使用MetaPost 实例的键设置文本,defaultfont
如果不想使用专用实例,则重新定义:
defaultfont := "Sans sa 1.2";
标签(btex textext(文本)etex,来源);
不要放在textext(…)
两者之间btex…etex
。选择其中一个
draw textext("Foo"); %% draws using the body font
label("Foo", origin); %% draws using defaultfont
例子
现在让我们把所有这些放在一起,并创建一个具有所有提到的功能的完整示例。
\defineMPinstance
[piechartmp] [metafun]
[textstyle=bigbodyfont]
\setupbodyfont [pagella]
\startMPinclusions{piechartmp}
useplainlabels;
input piechartmp;
pc_Metafun := true;
vardef _makeText primary s =
textext(s)
enddef;
SetupPercent(this, "\%");
\stopMPinclusions
\startMPinitializations
ResetSegments;
\stopMPinitializations
\startuseMPgraphic{piechartmp::pie-segments}
Segment(28, "first"); Segment(28, "second");
Segment(32, "third"); Segment(12, "fourth");
\stopuseMPgraphic
\startuseMPgraphic{piechartmp::pie-one}
\includeMPgraphic{piechartmp::pie-segments}
PieChart(3cm, 1, 70, 0, 0);
\stopuseMPgraphic
\startuseMPgraphic{piechartmp::pie-two}
\includeMPgraphic{piechartmp::pie-segments}
PieChart(3cm, 1, 50, 0, .2);
Label.auto(0)(percent)(inwards,(1,1)) withcolor white;
\stopuseMPgraphic
\startuseMPgraphic{piechartmp::pie-three}
\includeMPgraphic{piechartmp::pie-segments}
PieChart(3cm, 1, 0, 0, .1);
Label.auto(0)(percent)(inwards,(0,1)) withcolor white;
Label.auto(0)(name)(outwards,0);
\stopuseMPgraphic
\startuseMPgraphic{piechartmp::pie-four}
\includeMPgraphic{piechartmp::pie-segments}
PieChart(3cm, 1, 60, 0, .2);
\stopuseMPgraphic
\starttext
\startcombination
{\useMPgraphic{piechartmp::pie-one}} {\useMPgraphic{piechartmp::pie-two}}
{\useMPgraphic{piechartmp::pie-three}} {\useMPgraphic{piechartmp::pie-four}}
\stopcombination
\stoptext
最后的想法
请考虑一下,饼图是一种非常糟糕的数据可视化方式,如果可能的话,你应该避免使用它们,尤其是三维饼图。我在这里只提供一些链接。