Detection and styling of multiple functions in Mathematica's Plot

后端 未结 2 1926
盖世英雄少女心
盖世英雄少女心 2021-02-13 18:31

This question started me thinking about how Mathematica detects multiple functions being plotted. I find that I really do not understand the process.

Consider:

2条回答
  •  有刺的猬
    2021-02-13 19:01

    Well, it knows that there three arguments just so:

    In[13]:= Function[x, Length[Unevaluated[x]], HoldAll][{1, 
      Sequence[2, 3], 4}]
    
    Out[13]= 3
    

    If x is allowed to evaluate, then

    In[14]:= Function[x, Length[x], HoldAll][{1, Sequence[2, 3], 4}]
    
    Out[14]= 4
    

    EDIT: One sees it better with:

    In[15]:= Hold[{1, Sequence[2, 3], 4}]
    
    Out[15]= Hold[{1, Sequence[2, 3], 4}]
    

    in other words, flattening of Sequence requires evaluator.

    EDIT 2: I clearly missed the real question posed and will try to answer it now.

    Once Plot determines the number of argument it builds {{ style1, Line ..}, {style2, Line..}, ... }. In the case of {1,Sequence[2,3],4} we get the following structure:

    In[23]:= Cases[
      Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, 
       PlotRange -> {0, 5}], {_Hue, __Line}, 
      Infinity] /. {x_Line :> Line, _Hue -> Hue}
    
    Out[23]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}
    

    When plotting {1,{2,3},4} we get a different structure:

    In[24]:= Cases[
      Plot[{1, List[2, 3], 4}, {x, 0, 1}, 
       PlotRange -> {0, 5}], {_Hue, __Line}, 
      Infinity] /. {x_Line :> Line, _Hue -> Hue}
    
    Out[24]= {{Hue, Line}, {Hue, Line}, {Hue, Line}, {Hue, Line}}
    

    because lists would be flattened, just not using the evaluator. So as you see the tagging in the same color occurs because Sequence[2,3] is treated as a black-box function which returns a list of two elements:

    In[25]:= g[x_?NumberQ] := {2, 3}
    
    In[26]:= Cases[
      Plot[{1, g[x], 4}, {x, 0, 1}, PlotRange -> {0, 5}], {_Hue, __Line}, 
      Infinity] /. {x_Line :> Line, _Hue -> Hue}
    
    Out[26]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}
    

    I was trying to build a top-level implementation which would build such a structure, but one has to fight the evaluator. For example:

    In[28]:= Thread /@ Function[x,
       Thread[{Hold @@ {Range[Length[Unevaluated[x]]]}, Hold[x]}, Hold]
       , HoldAll][{1, Sequence[2, 3], 4}]
    
    Out[28]= Hold[Thread[{{1, 2, 3}, {1, Sequence[2, 3], 4}}]]
    

    Now we have to evaluate the Thread without evaluating its arguments, which would give {{1, 1}, {2, Sequence[2,3]}, {3, 4}}, where the first element of the list is a tag, and the subsequent once are functions to be sampled.

    Hope this helps.

提交回复
热议问题