Comment puis-je tracer une liste renvoyée par la solution Mathematica à des équations entières bornées
-
14-11-2019 - |
Question
J'ai donc un ensemble d'équations diophantines délimitées qui spécifient les lignes dans le plan. Je veux faire tracer Mathematica l'intersection de deux de ces équations afin que je puisse voir à quoi ils ressemblent.
Jusqu'à présent, j'ai quelque chose comme:
Solve [0 <x - y <3 && -1 <2 x - y <2, {x, y}, entiers
qui renvoie une structure comme:
{{x -> -2, y -> -4}, {x -> -1, y -> -3}, {x -> -1, y -> -2}, {x -> 0, y -> -1}}
Mais comment puis-je maintenant faire de Mathematica tracer ceci afin que je puisse voir la forme résultante. De préférence, je voudrais que l'intrigue considère chaque «point» comme un carré 1x1.
De plus, je me demande s'il existe une meilleure façon de faire de telles choses. Merci.
La solution
Définissez les données que vous souhaitez tracer en transformant la liste Solve[]
Retour. Cela peut faire comme
data = {x, y} /. Solve[0 < x - y < 3 && -1 < 2 x - y < 2, {x, y}, Integers]
Plus généralement, vous pouvez faire Solve
Renvoyez la solution dans un format de liste (plutôt que comme un ensemble de règles) en utilisant l'astuce suivante:
data = Solve[0 < x - y < 3 && -1 < 2 x - y < 2, {x, y}, Integers] /. Rule[a_,b_]->b
Pour le complot, parmi de nombreuses alternatives, vous pouvez utiliser ListPlot
comme
ListPlot[data, PlotMarkers -> {Style["\[FilledSquare]", FontSize -> 16]}]
Pour obtenir la sortie suivante
Vous pouvez l'affiner davantage en utilisant de nombreux styles et autres options de ListPlot
. Par exemple, vous pouvez rejoindre les points
ListPlot[data, PlotMarkers -> {Style["\[FilledSquare]", FontSize -> 16]},
Joined -> True]
pour obtenir
EDIT: Pour jouer avec le placement et la taille du marqueur, il existe plusieurs alternatives. Utilisant ListPlot
Vous pouvez obtenir ce dont vous avez besoin de l'une ou l'autre des deux manières:
(* Alternative 1: use fontsize to change the marker size *)
lp1 := ListPlot[{#} & /@ #1,
PlotMarkers -> {Style["\[FilledSquare]", FontSize -> Scaled[#2]]},
AspectRatio -> 1, AxesOrigin -> {0, 0},
PlotRange -> {{-5, 1}, {-5, 1}},
PlotStyle -> Hue /@ RandomReal[1, {Length@#1}],
Epilog -> {GrayLevel[.3], PointSize[.02], Point@#1, Thick,
Line@#1}, Frame -> True, FrameTicks -> All] &;
(* usage example *)
lp1 @@ {data, .30}
(* Alternative 2: use the second parameter of PlotMarkers to control scaled size *)
lp2 := ListPlot[{#} & /@ #1,
PlotMarkers -> {Graphics@{Rectangle[]}, #2}, AspectRatio -> 1,
AxesOrigin -> {0, 0}, PlotRange -> {{-5, 1}, {-5, 1}},
PlotStyle -> Hue /@ RandomReal[1, {Length@#1}],
Epilog -> {GrayLevel[.3], PointSize[.02], Point@#1, Thick,
Line@#1}, Frame -> True, FrameTicks -> All] &
(* usage example *)
lp2 @@ {data, 1/5.75}
Dans les deux cas, vous devez utiliser Epilog
, Sinon, les points de jonction des lignes sont occlus par les marqueurs. Les deux alternatives produisent la sortie suivante:
Alternativement, vous pouvez utiliser Graphics
, RegionPlot
, ContourPlot
, BubbleChart
avec des transformations appropriées de data
pour obtenir des résultats similaires à celui de ListPlot
sortie ci-dessus.
Utilisation de primitives graphiques:
(* data transformation to define the regions *)
trdataG[data_, size_] := data /. {a_, b_} :>
{{a - size/2, b - size/2}, {a + size/2, b + size/2}};
(* plotting function *)
gr := Graphics[
{
{Hue[RandomReal[]], Rectangle[##]} & @@@ trdataG @@ {#1, #2},
GrayLevel[.3], PointSize[.02], Thick, Point@#1, Line@#1},
PlotRange -> {{-5, 1}, {-5, 1}
},
PlotRangePadding -> 0, Axes -> True, AxesOrigin -> {0, 0},
Frame -> True, FrameTicks -> All] &
(* usage example *)
gr @@ {data, .99}
Utilisation de Bubblechart:
(* Transformation of data to a form that BubbleChart expects *)
dataBC[data_] := data /. {a_, b_} :> {a, b, 1};
(* custom markers *)
myMarker[size_][{{xmin_, xmax_}, {ymin_, ymax_}}, ___] :=
{EdgeForm[], Rectangle[{(1/2) (xmin + xmax) - size/2, (1/2) (ymin + ymax) -
size/2}, {(1/2) (xmin + xmax) + size/2, (1/2) (ymin + ymax) + size/2}]};
(* charting function *)
bc := BubbleChart[dataBC[#1], ChartElementFunction -> myMarker[#2],
ChartStyle -> Hue /@ RandomReal[1, {Length@#1}], Axes -> True,
AxesOrigin -> {0, 0}, PlotRange -> {{-5, 1}, {-5, 1}},
PlotRangePadding -> 0, AspectRatio -> 1, FrameTicks -> All,
Epilog -> {GrayLevel[.3], PointSize[.02], Point@#1, Thick, Line@#1}] &
(* usage example *)
bc @@ {data, .99}
Utilisation de RegionPlot:
(* Transformation of data to a form that RegionPlot expects *)
trdataRP[data_, size_] := data /. {a_, b_} :>
a - size/2 <= x <= a + size/2 && b - size/2 <= y <= b + size/2
(* charting function *)
rp := RegionPlot[Evaluate@trdataRP[#1, #2], {x, -5, 1}, {y, -5, 1},
AspectRatio -> 1, Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> {{-5, 1}, {-5, 1}},
PlotStyle -> Hue /@ RandomReal[1, {Length@#1}], FrameTicks -> All,
PlotPoints -> 100, BoundaryStyle -> None,
Epilog -> {GrayLevel[.3], PointSize[.02], Point@#1, Thick, Line@#1}] &
(* usage example *)
rp @@ {data, .99}
Utilisation de contourplot:
(* Transformation of data to a form that ContourPlot expects *)
trdataRP[data_, size_] := data /. {a_, b_} :>
a - size/2 <= x <= a + size/2 && b - size/2 <= y <= b + size/2;
trdataCP[data_, size_] := Which @@ Flatten@
Thread[{trdataRP[data, size], Range@Length@data}];
(* charting function *)
cp := ContourPlot[trdataCP[#1, #2], {x, -5, 1}, {y, -5, 1},
AspectRatio -> 1, Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> {{-5, 1}, {-5, 1}}, FrameTicks -> All,
ExclusionsStyle -> None, PlotPoints -> 100,
ColorFunction -> Hue,
Epilog -> {GrayLevel[.3], PointSize[.02], Point@#1, Thick, Line@#1}] &
(* usage example *)
cp @@ {data, .99}
Autres conseils
Peut être
sol = Solve[0 < x - y < 3 && -1 < 2 x - y < 2, {x, y}, Integers];
pts = Cases[sol, {_ -> n_, _ -> m_} :> {n, m}];
ListPlot[pts, Mesh -> All, Joined -> True, AxesOrigin -> {0, 0},
PlotMarkers -> {Automatic, 10}]
Peut également extraire les points à tracer en utilisant
{#[[1, 2]], #[[2, 2]]} & /@ sol