为什么Inset项目不会在Prolog中显示?

时间:2011-08-01 04:22:55

标签: graphics wolfram-mathematica

我为这个问题的长度道歉。我目前的Mathematica编程项目涉及复制我的雇佣机构对出版质量时间序列图的非常具体的业务规则。其中一个规则是多面板图形的面板标题和字幕位于绘图区域顶部附近。这使用PrologInset工作正常,直到我重新编写函数的那一部分以允许包含显式Prolog元素。然后,只显示Prolog选项中传递的项目,而不是面板标题和副标题。如果没有明确的Prolog选项,则面板标题和副标题显示正常。

为了进一步说明,想象一下函数体是一个很大的Module,包括局部变量pl=OptionValue[Prolog]mp=OptionValue[MultiPanel]

这个定义进一步向下(ppltitlesubtitle也被定义为局部变量,Rfontframecol是定义的常量包中的其他地方,即"Arial""Black"):

ppl=If[mp===False,pl,If[Length[pl]>0,Join[{ 
If[ToString[subtitle] == "None",  Inset[
DisplayForm[GridBox[{{Style[title, 20, FontFamily -> Rfont, framecol]}}]],
    Scaled[{0.5,0.96}],{Center,Top} ], 
Inset[DisplayForm[
GridBox[{{Style[title, 20, FontFamily -> Rfont, framecol]}, 
     {Style[subtitle, 16, FontFamily -> Rfont, framecol]}}, 
     RowSpacings -> 0]],Scaled[{0.5,0.98}],{Center,Top}] ]},pl],
  {If[ToString[subtitle] == "None",  
     Inset[ DisplayForm[
       GridBox[{{Style[title, 20, FontFamily -> Rfont, framecol]}}]],
      Scaled[{0.5,0.96}],{Center,Top} ], 
      Inset[DisplayForm[
        GridBox[{{Style[title, 20, FontFamily -> Rfont, framecol]}, 
                  {Style[subtitle, 16, FontFamily -> Rfont, framecol]}},
        RowSpacings -> 0]],Scaled[{0.5,0.98}],{Center,Top}]] }] ]

尽可能好。如果选项Inset(以及MultiPanel)不是mp并且没有明确设置False,则会使用Prolog。但是,如果设置了序言,例如Prolog -> {Text["test", Scaled[{0.6,0.5 }]]},则Inset不会显示,只会显示Text元素。

我加入他们的方式不是问题。捕获并打印ppl的值会产生:

{Inset[{{Style["This is a test", LineColor -> GrayLevel[0], 
FrontFaceColor -> GrayLevel[0],   BackFaceColor -> GrayLevel[0], 
GraphicsColor -> GrayLevel[0], FontFamily -> "Arial", FontSize -> 20, 
FontColor -> GrayLevel[0]]}, 
{Style["Year-ended percentage change", LineColor -> GrayLevel[0], 
FrontFaceColor -> GrayLevel[0], BackFaceColor -> GrayLevel[0], 
GraphicsColor -> GrayLevel[0], FontFamily -> "Arial", FontSize -> 16, 
FontColor -> GrayLevel[0]]}}, 
Scaled[{0.5, 0.98}], {Center, Top}], Text["test", Scaled[{0.6, 0.5}]]}

(是的,这些是一堆无证的选项,我将在另一个问题中提出这些选项。)

是否有人知道在一组图形选项中组合Prolog元素和其他内容是否有阻止Epilog(或Inset)的事情?

2 个答案:

答案 0 :(得分:3)

由于您没有提供有效的代码片段,我不确定其中出现了什么问题。

我的简单示例如何不复制您正在尝试的内容?

plot = Plot[x^2, {x, -5, 5}, Prolog -> Inset[Style[Text[":) = \[HappySmiley]"], Large]]]

enter image description here

pl = Flatten@{Prolog /. AbsoluteOptions[plot, Prolog]}

enter image description here

join = Show[{Plot[x^2 + 1, {x, -5, 5}, PlotStyle -> Red], 
             Plot[x^2, {x, -5, 5}, PlotStyle -> Blue]}, 
            Prolog -> Join[{Inset[Graphics@Circle[]]}, If[Length[pl] > 0, pl, {}]]]

enter image description here

答案 1 :(得分:3)

我现在觉得有点傻。我解决了这个问题。让我看看我是否能够清楚地解释清楚。

假设您有一个基于内置函数(例如XYZPlot)构建的自定义函数(例如,DateListPlot)。假设您要将一些选项传递给DateListPlot,以及处理某些特定于XYZPlot的选项。然后,您可能希望在之前传递用户明确之前包含的任何选项,并传递适用于自定义函数的默认选项。这是一个玩具示例:通常您可以使用PlotRange等将默认SetOptions设置为自定义函数的选项。

defaultplotrange = {1,5};
XYZPlot[args___,opts:OptionsPattern[{XYZPlot,DateListPlot}]]:=
  DateListPlot[args,Sequence @@ FilterRules[{opts}, Options[DateListPlot]],
    PlotRange->defaultplotrange]

到目前为止一切顺利。但是如果你想捕获一个选项的值并修改它即使用户在调用函数时为它提供一个显式值,例如添加[ahem]面板标题,如果有其他选项设置为True,然后您不能在FilterRules位之后放置该选项。它必须来。否则,将使用用户给出的Prolog的值,而不是添加了位的值。所以正确的方法是做这样的事情。

defaultplotrange = {1,5};
XYZPlot[args___,opts:OptionsPattern[{XYZPlot,DateListPlot}]]:=
  With[{pl=OptionValue[Prolog],mp=OptionValue[MultiPanel]},
  DateListPlot[args,
  Prolog -> If[mp===False,pl,Join[pl,{Inset[(* something else *)]}]],
  Sequence @@ FilterRules[{opts}, Options[DateListPlot]],
    PlotRange->defaultplotrange]]

很抱歉打扰你们所有人。