Построение числовой линии в Mathematica - PullRequest
10 голосов
/ 23 июля 2011

Я бы хотел построить простой интервал на числовой линии в Mathematica. Как мне это сделать?

Ответы [ 5 ]

10 голосов
/ 23 июля 2011

Для построения открытых или закрытых интервалов вы можете сделать что-то вроде:

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}, ")"]

enter image description here

Редактировать

Ниже следует замечательное расширение, сделанное @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}, ")"}}]

enter image description here

6 голосов
/ 24 июля 2011

Вот еще одна попытка, которая рисует числовые линии с более обычными белыми и черными кружками, хотя любой графический элемент, который вы хотите, может быть легко заменен.

Это зависит от LogicalExpand[Simplify@Reduce[expr, x]] и Sort, чтобы получитьвыражение в нечто похожее на каноническую форму, над которой могут работать правила замены.Это не всесторонне проверено и, вероятно, немного хрупко.Например, если значение expr уменьшается до True или False, мой код не умирает изящно.

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}]
  ]

(Примечание: я изначально пытался использовать Arrow и Arrowheadsрисовать линии - но поскольку Arrowheads автоматически изменяет масштаб стрелок относительно ширины охватывающей графики, это доставляет мне слишком много головной боли.)

ОК, некоторые примеры:

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

enter image description here
enter image description here
enter image description here

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

enter image description here

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

enter image description here

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

enter image description here

Редактировать: Давайте сравним вышеприведенное с выводом 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"}]

output of the above

Обратите внимание (при просмотре вышеупомянутого в сеансе Mathematica или на веб-сайте W | A) показываются всплывающие подсказки о важных точках и серых динамических линиях сетки.Я украл эти идеи и включил их в отредактированный numLine[] код выше.

Вывод WolframAlpha не совсем обычный Graphics объект, поэтому трудно изменить его Options илиобъединить, используя Show.Чтобы увидеть различные объекты нумерации, которые Wolfram | Alpha может вернуть, запустите WolframAlpha["x>0", {{"NumberLine"}}] - «Content», «Cell» и «Input» возвращают в основном один и тот же объект.В любом случае, чтобы получить графический объект из

wa = WolframAlpha["x>0", {{"NumberLine", 1}, "Content"}]

, вы можете, например, запустить

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

Затем мы можем изменить графические объекты и объединить их в сетку, чтобы получить

aligned

6 голосов
/ 23 июля 2011

Вот уродливое решение, использующее 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]

example 1

Можно использовать любую переменную:

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

example 2

Reduce s посторонние неравенства, сравните следующее:

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

example 3

3 голосов
/ 16 июня 2015

Начиная с Mathematica 10, доступно NumberLinePlot.

0 голосов
/ 23 июля 2011

Выполните обычное Plot и установите Axes -> {True, False} (и скрывайте ограничивающий прямоугольник, если он существует, чего обычно нет).Отрегулируйте размер изображения или формат изображения соответствующим образом.

например

Plot[
    Piecewise[{
        {0, And[0<x, x<1]}
    }],
    {x,-1,2},
    Axes -> {True, False}        
]

Вы можете использовать Show, чтобы объединить это с представлением открытых и закрытых точек.

Существует небольшая вероятность, что вам, возможно, придется передать Indeterminate или какое-либо другое специальное значение в качестве второго аргумента Piecewise (или же по умолчанию оно равно 0), если вы неправильно установите ширину линии или похожие стили печати;или, альтернативно, но более надежно, установите значение 999 и PlotRange -> {{-1,2},{-.1,.1}}.

...