Почему элемент Inset не отображается в Prolog на графике? - PullRequest
1 голос
/ 01 августа 2011

Я прошу прощения за длину этого вопроса. Мой нынешний программный проект Mathematica включает в себя копирование очень специфических бизнес-правил, которые есть в моем учреждении, для графиков временных рядов с качеством публикации. Одно из этих правил заключается в том, что многопанельные графы имеют заголовки панелей и субтитры по центру в верхней части области графика. Это работало нормально, используя Prolog и Inset, пока я не переделал этот бит функции, чтобы разрешить включение явных элементов Prolog. Затем отображается только элемент, переданный в параметре Prolog, а не заголовки и субтитры панели. Если нет явной опции Prolog, заголовки и субтитры панели отображаются нормально.

Для более подробного объяснения, представьте, что тело функции находится в большом Module, включая локальные переменные pl=OptionValue[Prolog] и mp=OptionValue[MultiPanel].

Чуть дальше это определение (ppl, title и subtitle также были определены как локальные переменные, а Rfont и framecol - это константы, определенные в других местах пакета, а именно "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 ]

3 голосов
/ 01 августа 2011

Я чувствую себя немного глупо сейчас.Я решил проблему.Позвольте мне посмотреть, смогу ли я объяснить достаточно ясно.

Предположим, у вас есть пользовательская функция (скажем, 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]]

Извините, что беспокою вас всех.

3 голосов
/ 01 августа 2011

Поскольку вы не указали рабочий фрагмент кода, я не уверен, что в нем не так.

Как мой простой пример не повторяет то, что вы пытаетесь?

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

...