在Mathematica中绘制数字行

问题描述 投票:10回答:6

我想在Mathematica中的数字线上绘制一个简单的间隔。我该怎么做?

wolfram-mathematica intervals
6个回答
6
投票

[这是另一种尝试用更常规的白色和黑色圆圈绘制数字线的方法,尽管您想要的任何图形元素都可以轻松换出。

它依靠LogicalExpand[Simplify@Reduce[expr, x]]Sort将表达式转换为类似于替换规则可以使用的规范形式的表达式。这未经广泛测试,可能有点脆弱。例如,如果给定的expr减少为TrueFalse,我的代码将无法正常死机。

numLine[expr_, x_Symbol:x, range:{_, _}:{Null, Null}, 
  Optional[hs:_?NumericQ, 1/30], opts:OptionsPattern[]] := 
 Module[{le = {LogicalExpand[Simplify@Reduce[expr, x]]} /. Or -> List,
   max, min, len, ints = {}, h, disk, hArrow, lt = Less|LessEqual, gt = Greater|GreaterEqual},
  If[TrueQ@MatchQ[range, {a_, b_} /; a < b],
   {min, max} = range,
   {min, max} = Through[{Min, Max}@Cases[le, _?NumericQ, \[Infinity]]]];
  len =Max[{max - min, 1}]; h = len hs;
  hArrow[{x1_, x2_}, head1_, head2_] := {{Thick, Line[{{x1, h}, {x2, h}}]},
                                         Tooltip[head1, x1], Tooltip[head2, x2]};
  disk[a_, ltgt_] := {EdgeForm[{Thick, Black}], 
    Switch[ltgt, Less | Greater, White, LessEqual | GreaterEqual, Black], 
    Disk[{a, h}, h]};
  With[{p = Position[le, And[_, _]]}, 
       ints = Extract[le, p] /. And -> (SortBy[And[##], First] &); 
       le = Delete[le, p]];   
  ints = ints /. (l1 : lt)[a_, x] && (l2 : lt)[x, b_] :> 
     hArrow[{a, b}, disk[a, l1], disk[b, l2]];
  le = le /. {(*_Unequal|True|False:>Null,*)
     (l : lt)[x, a_] :> (min = min - .3 len; 
       hArrow[{a, min}, disk[a, l], 
        Polygon[{{min, 0}, {min, 2 h}, {min - Sqrt[3] h, h}}]]),
     (g : gt)[x, a_] :> (max = max + .3 len; 
       hArrow[{a, max}, disk[a, g], 
        Polygon[{{max, 0}, {max, 2 h}, {max + Sqrt[3] h, h}}]])};
  Graphics[{ints, le}, opts, Axes -> {True, False}, 
   PlotRange -> {{min - .1 len, max + .1 len}, {-h, 3 h}},
   GridLines -> Dynamic[{{#, Gray}} & /@ MousePosition[
                           {"Graphics", Graphics}, None]], 
   Method -> {"GridLinesInFront" -> True}]
  ]

((注:我本来尝试使用ArrowArrowheads画线-但由于Arrowheads会根据周围图形的宽度自动缩放箭头,这让我头疼不已。 )

确定,例如:

numLine[0 < x], 
numLine[0 > x]
numLine[0 < x <= 1, ImageSize -> Medium]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9BSEtLSS5wbmcifQ==” alt =“在此处输入图像描述”>“在此处输入图像描述”“在此处输入图像描述”

numLine[0 < x <= 1 || x > 2, Ticks -> {{0, 1, 2}}]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9GZ3ltZC5wbmcifQ==” alt =“在此处输入图像描述”>

numLine[x <= 1 && x != 0, Ticks -> {{0, 1}}]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9lU0N2ci5wbmcifQ==” alt =“在此处输入图像描述”>

GraphicsColumn[{
  numLine[0 < x <= 1 || x >= 2 || x < 0],
  numLine[0 < x <= 1 || x >= 2 || x <= 0, x, {0, 2}]
  }]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9Ob0ZXWi5wbmcifQ==” alt =“在此处输入图像描述”>

编辑:让我们将以上内容与Wolfram|Alpha]的输出进行比较

WolframAlpha["0 < x <= 1 or x >= 2 or x < 0", {{"NumberLine", 1}, "Content"}]
WolframAlpha["0 < x <= 1 or x >= 2 or x <= 0", {{"NumberLine", 1}, "Content"}]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9GMVlzNS5wbmcifQ==” alt =“以上输出”>“>

请注意(在Mathematica会话中或在W | A网站上查看以上内容时,请注意重要点和灰色动态网格线上的精美工具提示。我已经窃取了这些想法,并将它们合并到上面已编辑的numLine[]代码中。

WolframAlpha的输出不是普通的Graphics对象,因此很难修改其Options或使用Show进行合并。要查看Wolfram | Alpha可以返回的各种数字线对象,请运行WolframAlpha["x>0", {{"NumberLine"}}]-“内容”,“单元格”和“输入”全部返回基本上相同的对象。无论如何,要从

获取图形对象
wa = WolframAlpha["x>0", {{"NumberLine", 1}, "Content"}]

例如,您可以运行

Graphics@@First@Cases[wa, GraphicsBox[__], Infinity, 1]

然后,我们可以修改图形对象并将它们组合在网格中以得到

“

对于绘制打开或关闭间隔,您可以执行以下操作:

intPlot[ss_, {s_, e_}, ee_] := Graphics[{Red, Thickness[.01],
   Text[Style[ss, Large, Red, Bold], {s, 0}],
   Text[Style[ee, Large, Red, Bold], {e, 0}],
   Line[{{s, 0}, {e, 0}}]},
  Axes -> {True, False},
  AxesStyle -> Directive[Thin, Blue, 12],
  PlotRange -> {{ s - .2 Abs@(s - e), e + .2 Abs@(s - e)}, {0, 0}},
  AspectRatio -> .1]

intPlot["[", {3, 4}, ")"]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9KQjNGRS5wbmcifQ==” alt =“在此处输入图像描述”>

编辑

以下是@Simon做的很好的扩展名,可能是我再次尝试解决重叠间隔问题时宠坏了。

intPlot[ss_, {s_, e_}, ee_] := intPlot[{{ss, {s, e}, ee}}]
intPlot[ints : {{_String, {_?NumericQ, _?NumericQ}, _String} ..}] :=
 Module[{i = -1, c = ColorData[3, "ColorList"]},
  With[
   {min = Min[ints[[All, 2, 1]]], max = Max[ints[[All, 2, 2]]]},
   Graphics[Table[
     With[{ss = int[[1]], s = int[[2, 1]], e = int[[2, 2]], ee = int[[3]]}, 
       {c[[++i + 1]], Thickness[.01],
       Text[Style[ss, Large, c[[i + 1]], Bold], {s, i}], 
       Text[Style[ee, Large, c[[i + 1]], Bold], {e, i}],
       Line[{{s, i}, {e, i}}]}], {int, ints}], 
    Axes -> {True, False}, 
    AxesStyle -> Directive[Thin, Blue, 12], 
    PlotRange -> {{min - .2 Abs@(min - max), max + .2 Abs@(min - max)}, {0, ++i}}, 
    AspectRatio -> .2]]]

(*Examples*)

intPlot["[", {3, 4}, ")"]
intPlot[{{"(", {1, 2}, ")"}, {"[", {1.5, 4}, ")"}, 
        {"[", {2.5, 7}, ")"}, {"[", {1.5, 4}, ")"}}]

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9wdkUxdS5wbmcifQ==” alt =“在此处输入图像描述”>

这里是使用RegionPlot的丑陋解决方案。开放式限制使用虚线表示,封闭式限制使用实线表示

numRegion[expr_, var_Symbol:x, range:{xmin_, xmax_}:{0, 0}, opts:OptionsPattern[]] :=
            Module[{le=LogicalExpand[Reduce[expr,var,Reals]],
                    y, opendots, closeddots, max, min, len},
 opendots =   Cases[Flatten[le/.And|Or->List], n_<var|n_>var|var<n_|var>n_:>n];
 closeddots = Cases[Flatten[le/.And|Or->List], n_<=var|n_>=var|var<=n_|var>=n_:>n];
 {max, min} = If[TrueQ[xmin < xmax], {xmin, xmax}, 
                 {Max, Min}@Cases[le, _?NumericQ, Infinity] // Through];
 len = max - min;
 RegionPlot[le && -1 < y < 1, {var, min-len/10, max+len/10}, {y, -1, 1},
            Epilog -> {Thick, Red, Line[{{#,1},{#,-1}}]&/@closeddots,
                       Dotted, Line[{{#,1},{#,-1}}]&/@opendots},
            Axes -> {True,False}, Frame->False, AspectRatio->.05, opts]]

减少绝对值的示例:

numRegion[Abs[x] < 2]

“示例1”

可以使用任何变量:

numRegion[0 < y <= 1 || y >= 2, y]

“示例2”

Reduce的外部不平等,请进行以下比较:

GraphicsColumn[{numRegion[0 < x <= 1 || x >= 2 || x < 0],
                numRegion[0 < x <= 1 || x >= 2 || x <= 0, x, {0, 2}]}]

“示例3”

从Mathematica 10开始,有NumberLinePlot可用。

以前的丑陋解决方案帮助我开发了InequalityPlot函数,以解决和跟踪两个变量中的不等式。

NumberLinePlot

执行常规的InequalityPlot[ineq_, {x_Symbol, xmin_, xmax_},{y_Symbol, ymin_, ymax_}, opts : OptionsPattern[Join[Options[ContourPlot], Options[RegionPlot], {CurvesColor -> RGBColor[1, .4, .2]}]]] := Module[{le = LogicalExpand[ineq], opencurves, closedcurves, curves}, opencurves = Cases[Flatten[{le /. And | Or -> List}], lexp_ < rexp_ | lexp_ > rexp_ | lexp_ < rexp_ | lexpr_ > rexp_ :> {lexp == rexp, Dashing[Medium]}]; closedcurves = Cases[Flatten[{le /. And | Or -> List}], lexp_ <= rexp_ | lexp_ >= rexp_ | lexp_ <= rexp_ | lexp_ >= rexp_ :> {lexp == rexp, Dashing[None]}]; curves = Join[opencurves, closedcurves]; Show[ RegionPlot[ineq, {x, xmin, xmax}, {y, ymin, ymax}, BoundaryStyle -> None, Evaluate[Sequence @@ FilterRules[{opts}, Options[RegionPlot]]]], ContourPlot[First[#] // Evaluate, {x, xmin, xmax}, {y, ymin, ymax}, ContourStyle -> Directive[OptionValue[CurvesColor], Last[#]], Evaluate[Sequence @@ FilterRules[{opts}, Options[ContourPlot]]]] & /@ curves ] ] ,然后设置Plot(如果存在边界框,则通常隐藏一个边界框,然后隐藏边界框)。适当调整图像尺寸或宽高比。

例如

Axes -> {True, False}

您可以使用Plot[ Piecewise[{ {0, And[0<x, x<1]} }], {x,-1,2}, Axes -> {True, False} ] 将其与打开和关闭的点的想象结合起来。

[如果您未正确设置线宽或类似图形,则极有可能需要将Show或其他一些特殊值作为Indeterminate的第二个参数(否则默认为0)。样式或者,或者更确定地,将值设置为999和Piecewise


10
投票

对于绘制打开或关闭间隔,您可以执行以下操作:


6
投票

这里是使用RegionPlot的丑陋解决方案。开放式限制使用虚线表示,封闭式限制使用实线表示


3
投票

从Mathematica 10开始,有NumberLinePlot可用。


0
投票

以前的丑陋解决方案帮助我开发了InequalityPlot函数,以解决和跟踪两个变量中的不等式。


-1
投票

执行常规的InequalityPlot[ineq_, {x_Symbol, xmin_, xmax_},{y_Symbol, ymin_, ymax_}, opts : OptionsPattern[Join[Options[ContourPlot], Options[RegionPlot], {CurvesColor -> RGBColor[1, .4, .2]}]]] := Module[{le = LogicalExpand[ineq], opencurves, closedcurves, curves}, opencurves = Cases[Flatten[{le /. And | Or -> List}], lexp_ < rexp_ | lexp_ > rexp_ | lexp_ < rexp_ | lexpr_ > rexp_ :> {lexp == rexp, Dashing[Medium]}]; closedcurves = Cases[Flatten[{le /. And | Or -> List}], lexp_ <= rexp_ | lexp_ >= rexp_ | lexp_ <= rexp_ | lexp_ >= rexp_ :> {lexp == rexp, Dashing[None]}]; curves = Join[opencurves, closedcurves]; Show[ RegionPlot[ineq, {x, xmin, xmax}, {y, ymin, ymax}, BoundaryStyle -> None, Evaluate[Sequence @@ FilterRules[{opts}, Options[RegionPlot]]]], ContourPlot[First[#] // Evaluate, {x, xmin, xmax}, {y, ymin, ymax}, ContourStyle -> Directive[OptionValue[CurvesColor], Last[#]], Evaluate[Sequence @@ FilterRules[{opts}, Options[ContourPlot]]]] & /@ curves ] ] ,然后设置Plot(如果存在边界框,则通常隐藏一个边界框,然后隐藏边界框)。适当调整图像尺寸或宽高比。

© www.soinside.com 2019 - 2024. All rights reserved.