Could I specify different filling colors for within a single plot like the bellow or would I need to "Show" several Plots ? Let`s say I would like the filling style to be the same as the PlotStyle.
priorMean = 50;
priorVar = 100;
llhMean = 30;
llhVar = 40;
postMean=35.71;
postVar=28.57;
Plot[
Evaluate#MapThread[
Function[{\[Mu], \[Sigma]},
PDF[NormalDistribution[\[Mu], Sqrt[\[Sigma]]], x]],
{{priorMean, llhMean, postMean}, {priorVar, llhVar, postVar}}],
{x, 0, 100}, Filling -> Axis, PlotStyle -> {Red, Green, Blue}]
You'll need to use FillingStyle to fill in. I think you got stuck in the syntax for FillingStyle, which is not the same as that for PlotStyle, although you'd expect it to be. You'll have to assign a color for each curve as FillingStyle -> {1 -> color1, 2 -> color2}, etc. Here's an example:
colors = {Red, Green, Blue};
Plot[Evaluate#
MapThread[
Function[{\[Mu], \[Sigma]},
PDF[NormalDistribution[\[Mu], Sqrt[\[Sigma]]], x]], {{priorMean,
llhMean, postMean}, {priorVar, llhVar, postVar}}], {x, 0, 100},
Filling -> Axis, PlotStyle -> colors,
FillingStyle ->
MapIndexed[#2 -> Directive[Opacity[0.3], #] &, colors]]
I propose making an extension to the definition of Plot. I have done this before.
toDirective[{ps__} | ps__] := Flatten[Directive ## Flatten[{#}]] & /# {ps}
makefills = MapIndexed[#2 -> Join ## toDirective#{Opacity[0.3], #} &, #] &;
Unprotect[Plot];
Plot[a__, b : OptionsPattern[]] :=
Block[{$FSmatch = True},
With[{fills = makefills#OptionValue[PlotStyle]},
Plot[a, FillingStyle -> fills, b]
]] /; ! TrueQ[$FSmatch] /; OptionValue[FillingStyle] === "Match"
With this in place, you can use FillingStyle -> "Match" to auto-style the fills to match the main styles.
Plot[{Sin[x], Cos[x], Log[x]}, {x, 0, 2 Pi},
PlotRange -> {-2, 2},
PlotStyle -> {{Blue, Dashing[{0.04, 0.01}]},
{Thick, Dashed, Orange},
{Darker#Green, Thick}},
Filling -> Axis,
FillingStyle -> "Match"
]
You could do something like
With[{colours = {Red, Green, Blue}},
Plot[Evaluate#
MapThread[
Function[{\[Mu], \[Sigma]},
PDF[NormalDistribution[\[Mu], Sqrt[\[Sigma]]], x]],
{{priorMean, llhMean, postMean}, {priorVar, llhVar, postVar}}],
{x, 0, 100},
Filling ->
MapIndexed[#2[[1]] -> {Axis, Directive[Opacity[.3, #1]]} &, colours],
PlotStyle -> colours]]
This gets a result:
Plot[Evaluate#
MapThread[
Function[{\[Mu], \[Sigma]},
PDF[NormalDistribution[\[Mu], Sqrt[\[Sigma]]], x]], {{priorMean,
llhMean, postMean}, {priorVar, llhVar, postVar}}], {x, 0, 100},
Filling -> {1 -> {Axis, Red}, 2 -> {Axis, Green}, 3 -> {Axis, Blue}},
PlotStyle -> {Red, Green, Blue}]
Found in the help under FillingStyle, Scope, Filling Style.
And alternatively:
f = MapThread[
Function[{\[Mu], \[Sigma]},
PDF[NormalDistribution[\[Mu], Sqrt[\[Sigma]]], x]],
{{priorMean, llhMean, postMean}, {priorVar, llhVar, postVar}}];
c = {Red, Green, Blue};
Show[Array[
Plot[f[[#]], {x, 0, 100}, Filling -> {1 -> {Axis, c[[#]]}},
PlotRange -> {Automatic, 0.08}, PlotStyle -> c[[#]]] &, 3]]
Related
I've got a simple ListPlot like
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
Now I want to color specific points with RED, say every 5th point, I tried
mycolor[x_] /; Mod[x, 5] == 0 = Red;
mycolor[_] = Blue;
Now
ListPlot[#, PlotStyle -> AbsolutePointSize[3], ColorFunction ->
mycolor[#[[All, 1]], ColorFunctionScaling -> False]] &[list2]
doesnt work quite right, all points are still blue.
What is wrong here?
Thanks,
archi
Here is an easy way to get the result you're after :-
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
mycolor[x_] := If[Mod[x, 5] == 0, Red, Blue];
mycolors = mycolor /# list2[[All, 1]];
ListPlot[List /# list2,
PlotStyle -> Map[{AbsolutePointSize[3], #} &, mycolors]]
Alternatively, with a colour function, thanks to rm -rf's answer on george's link :-
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
mycolor = Function[{x, y}, If[Mod[x, 5] == 0, Red, Blue]];
ListLinePlot[list2,
PlotStyle -> AbsolutePointSize[3], ColorFunction -> mycolor,
ColorFunctionScaling -> False] /. Line -> Point
Further to comment
For different plot markers I have reverted to the easy method. In order to apply different styles and plot markers in ListPlot the differently styled points have to be in separate lists, hence List /# list2. (Only two lists would actually be necessary though.)
Clear[mycolor];
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
mycolor[x_] := If[Mod[x, 5] == 0,
{Red, "\[FilledUpTriangle]", 14},
{Blue, "\[FilledSmallCircle]", 6}];
mycolorspec = mycolor /# First /# list2;
ListPlot[List /# list2,
PlotMarkers -> Apply[Style[#2, FontSize -> #3, #1] &,
mycolorspec, {1}]]
I'm trying to combine 3 functions graphed on a Plot[] and 1 function graphed on a ParametricPlot[]. My equations are as follows:
plota = Plot[{-2 x, -2 Sqrt[x], -2 x^(3/5)}, {x, 0, 1}, PlotLegend -> {"-2 x", "-2 \!\(\*SqrtBox[\(x\)]\)", "-2 \!\(\*SuperscriptBox[\(x\), \(3/5\)]\)"}]
plotb = ParametricPlot[{2.4056 (u - Sin[u]), 2.4056 (Cos[u] - 1)}, {u,0, 1.40138}, PlotLegend -> {"Problem 3"}]
Show[plota, plotb]
This is the image it gives:
As yoda said, PlotLegends is terrible. However, if you don't mind setting the plot styles manually and repeating them lateron, ShowLegend can help.
plota = Plot[{-2 x, -2 Sqrt[x], -2 x^(3/5)}, {x, 0, 1},
PlotStyle -> {{Red}, {Blue}, {Orange}}];
plotb = ParametricPlot[{2.4056 (u - Sin[u]), 2.4056 (Cos[u] - 1)}, {u, 0, 1.40138},
PlotStyle -> {{Black}}];
And now
ShowLegend[Show[plota, plotb],
{{{Graphics[{Red, Line[{{0, 0}, {1, 0}}]}], Label1},
{Graphics[{Blue, Line[{{0, 0}, {1, 0}}]}], Label2},
{Graphics[{Orange, Line[{{0, 0}, {1, 0}}]}], Label3},
{Graphics[{Black, Line[{{0, 0}, {1, 0}}]}], Label4}},
LegendSize -> {0.5, 0.5}, LegendPosition -> {0.5, -0.2}}]
which will give you this:
You can also write some simple functions to make this a little less cumbersome, if you deal with this problem often.
Well, the root cause of the error is the PlotLegends package, which is a terrible, buggy package. Removing that, Show combines them correctly:
plota = Plot[{-2 x, -2 Sqrt[x], -2 x^(3/5)}, {x, 0, 1}]
plotb = ParametricPlot[{2.4056 (u - Sin[u]), 2.4056 (Cos[u] - 1)}, {u,
0, 1.40138}]
Show[plota, plotb]
You can see Simon's solution here for ideas to label your different curves without using PlotLegends. This answer by James also demonstrates why PlotLegends has the reputation it has...
You can still salvage something with the PlotLegends package. Here's an example using ShowLegends that you can modify to your tastes
colors = {Red, Green, Blue, Pink};
legends = {-2 x, -2 Sqrt[x], -2 x^(3/5), "Problem 3"};
plota = Plot[{-2 x, -2 Sqrt[x], -2 x^(3/5)}, {x, 0, 1},
PlotStyle -> colors[[1 ;; 3]]];
plotb = ParametricPlot[{2.4056 (u - Sin[u]), 2.4056 (Cos[u] - 1)}, {u,
0, 1.40138}, PlotStyle -> colors[[4]]];
ShowLegend[
Show[plota,
plotb], {Table[{Graphics[{colors[[i]], Thick,
Line[{{0, 0}, {1, 0}}]}], legends[[i]]}, {i, 4}],
LegendPosition -> {0.4, -0.15}, LegendSpacing -> 0,
LegendShadow -> None, LegendSize -> 0.6}]
As the other answers pointed out, the culprit is PlotLegend. So, sometimes is useful to be able to roll your own plot legends:
plotStyle = {Red, Green, Blue};
labls = {"a", "b", "Let's go"};
f[i_, s_] := {Graphics[{plotStyle[[i]], Line[{{0, 0}, {1, 0}}]},
ImageSize -> {15, 10}], Style[labls[[i]], s]};
Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 Pi},
PlotStyle -> plotStyle,
Epilog ->
Inset[Framed[Style#Column[{Grid[Table[f[i, 15], {i, 1, 3}]]}]],
Offset[{-2, -2}, Scaled[{1, 1}]], {Right, Top}],
PlotRangePadding -> 1
]
daList={{0.059, 0.298, 0.726, 0.735, 1.461, 2.311, 3.315},
{0.05, 0.404,0.664, 0.782, 1.376, 2.328, 3.432},
{0.087, 0.628, 0.986, 1.187,1.914, 3.481, 4.993},
{0.073, 0.594, 0.975, 1.147, 2.019, 3.417,5.037},
{0.143, 0.821, 1.442, 1.595, 2.983, 4.98, 7.604},
{0.107,0.871, 1.431, 1.684, 2.964, 5.015, 7.394}}
ListPlot[daList,
Joined -> True,
PlotRange -> {{1, 7}, {0, 7}},
PlotStyle -> {{Thick, Lighter[Red, .5]},
{Dashed, Black},
{Thick,Lighter[Red, .3]},
{Dashed, Black},
{Thick,Lighter[Red, .1]},
{Dashed, Black}},
Prolog ->{GrayLevel[0.5], EdgeForm[Thickness[.005]],
Rectangle[{1.01, 0.01}, {6.99, 6.99}]}]
As you can see, I need to assign different directive to each line.
I would like the Dashed Black Line to be Points (Joined->False).
I can`t grasp the methods to group directive for sublist yet.
Thank You for your attention.
If you want every other plot to be joined, you could just set Joined->{True, False}, e.g.
ListPlot[daList, Joined -> {True, False},
PlotRange -> {{1, 7}, {0, 7}},
PlotStyle -> {{Thick, Lighter[Red, .5]}, {Dashed, Black}, {Thick,
Lighter[Red, .3]}, {Dashed, Black}, {Thick,
Lighter[Red, .1]}, {Dashed, Black}},
Prolog -> {GrayLevel[0.5], EdgeForm[Thickness[.005]],
Rectangle[{1.01, 0.01}, {6.99, 6.99}]}]
which produces
Edit
Concerning your comment, I guess you could always plot the even and odd sets of points separately and combine them with show. So for your example:
joinedStyle = {Thick, Lighter[Red, #]} & /# {.5, .3, .1};
pointStyle = Black;
plot1 = ListPlot[daList[[1 ;; ;; 2]], Joined -> True, PlotStyle -> joinedStyle,
PlotRange -> {{1,7},{0,7}}];
plot2 = ListPlot[daList[[2 ;; ;; 2]], Joined -> False, PlotStyle -> pointStyle];
Show[plot1, plot2, PlotRange -> {{1, 7}, {0, 7}},
Prolog -> {GrayLevel[0.5], EdgeForm[Thickness[.005]],
Rectangle[{1.01, 0.01}, {6.99, 6.99}]}]
You may consider constructing your plots separately, and layering them with Show. Here is an example that hopefully is not too far from the mark.
{d1, d2} = Partition[daList, 2]\[Transpose];
lambda = {541, 550, 560, 570, 580, 590, 600};
colors = {Thick, Red~Lighter~#} & /# {0.5, 0.3, 0.1};
g1 = ListPlot[d1, Joined -> True, PlotStyle -> colors];
g2 = ListPlot[d2, PlotStyle -> {{Black, AbsolutePointSize[5]}}];
Show[{g1, g2}, PlotRange -> {{1, 7}, {0, 7}},
AspectRatio -> 1/GoldenRatio, Frame -> True, FrameStyle -> 20,
FrameTicks -> {{Automatic,
None}, {MapIndexed[{#2[[1]], #} &, lambda], Automatic}},
Prolog -> {GrayLevel[0.5], EdgeForm[Thickness[.005]],
Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}, ImageSize -> 600]
I think I am almost copying Heike here, but it is not intentional. Hopefully both answers add something.
There is a more complete example of the use of Scaled and ImageScaled for this very application in: https://stackoverflow.com/questions/6303500/mathematica-matlab-like-figure-plot
As an alternative to ListPlot, you could consider Graphics
tdata = MapIndexed[{#2[[1]], #1} &, #] & /# daList;
and
Graphics[
{ GrayLevel[0.7], EdgeForm[AbsoluteThickness[2]],
Rectangle[{1.02, 0.05}, {7.2, 7.75}],
(*lines*)
AbsoluteThickness[2],
Transpose[{Lighter[Red, #] & /# {0.5, 0.3, 0.1},
Line#tdata[[#]] & /# {1, 3, 5}}],
(*points*)
Black, PointSize[0.016],
Point#tdata[[#]] & /# {2, 4, 6}
}, Axes -> True, PlotRange -> {{1, 7.2}, {0, 7.8}},
AspectRatio -> 1/GoldenRatio]
gives
or, to give each data set a different symbol,as in the following plot:
Code:
Graphics[
{ GrayLevel[.7], EdgeForm[AbsoluteThickness[2]],
Rectangle[{1.02, 0.05}, {7.2, 7.75}],
(*lines*)
AbsoluteThickness[2],
Transpose[{Lighter[Red, #] & /# {0.5, 0.3, 0.1},
Line#tdata[[#]] & /# {1, 3, 5}}],
(*points*)
Inset[Graphics[{EdgeForm[Black], White, Rectangle[]},
ImageSize -> 8], #] & /# tdata[[2]],
Inset[Graphics[{EdgeForm[Black], White,
Polygon[{{1, 0}, {0, Sqrt[3]}, {-1, 0}}]},
ImageSize -> 10], #] & /# tdata[[4]],
Inset[Graphics[{ EdgeForm[Black], White, Disk[]},
ImageSize -> 9], #] & /# tdata[[6]]
}, Axes -> True, PlotRange -> {{1, 7.2}, {0, 7.8}},
AspectRatio -> 1/GoldenRatio]
I have a matrix of coordinates (X,Y), and I want to animate them by plotting point by point and connect the points. I tried "ListAnimate" but it only animates the values of each coordinate..
Here is what the sample look like:
{{1,1},
{1,2},
{5,4},...}
May be
max = 10;
coords = Table[{i, RandomReal[]}, {i, max}];
Animate[ListPlot[coords[[1 ;; n]], PlotMarkers -> {Automatic, Small},
Joined -> True, PlotRange -> {{0, max}, {0, 1}}], {n, 1, max, 1}]
Just an illustrative answer. All the following also do the same thing:
max = 10;
coords = Table[{i, RandomReal[]}, {i, max}];
p = PlotRange -> {{0, max}, {0, 1}};
Animate[
ListLinePlot[coords[[1 ;; n]], Mesh -> All, p],
{n, Range#max}]
Animate[
Graphics[{Point##, Line##}, p, Axes -> True] &#coords[[1 ;; n]],
{n, Range#max}]
Animate[
Graphics[{ Red, Point[#],
Black, BSplineCurve[#, SplineDegree -> 1]}, p] &#coords[[1 ;; n]],
{n, Range#max}]
Is it possible to zoom into a region and display it as a subplot within the same plot? Here is my primitive attempt at freehand graphics, to illustrate my question:
I can think of using Plot, and then Epilog, but then I get lost in the positioning and in giving the plot its own origin (When I try Epilog on Plot, the new plot lays on top of the old one, using the old one's origin).
Also, it would be nice if the positioning of the subplot can be input, as different curves have different "empty regions" that can be used to position the image.
I've seen this in several articles and I can do this in MATLAB, but I have no clue how to do it in mma.
Use Inset. Here's an example:
f[x_] = Sum[Sin[3^n x]/2^n, {n, 0, 20}];
x1 = x /. FindRoot[f[x] == -1, {x, -2.1}];
x2 = x /. FindRoot[f[x] == -1, {x, -1.1, -1}];
g = Plot[f[x], {x, x1, x2}, AspectRatio -> Automatic,
Axes -> False, Frame -> True, FrameTicks -> None];
{y1, y2} = Last[PlotRange /. FullOptions[g]];
Plot[Sum[Sin[3^n x]/2^n, {n, 0, 20}], {x, -Pi, Pi},
Epilog -> {Line[{
{{x2, y2 + 0.1}, {-0.5, 0.5}}, {{x1, y2 + 0.1}, {-3.5, 0.5}},
{{x1, y1}, {x2, y1}, {x2, y2 + 0.1}, {x1, y2 + 0.1}, {x1,
y1}}}],
Inset[g, {-0.5, 0.5}, {Right, Bottom}, 3]},
PlotRange -> {{-4, 4}, {-3, 3}}, AspectRatio -> Automatic]
And, borrowing from belisarius' code, you can also select the focus of your inset interactively by selecting a position at the x-axis:
imgsz = 400;
f[x_] := Piecewise[{{Sin#x, Abs#x > .1}, {Sin[100 x], Abs[x] <= 0.1}}];
Manipulate[
Plot[f[x], {x, -3, 3}, PlotRange -> {{-3, 3}, {-2, 5}},
ImageSize -> imgsz,
Epilog ->
Inset[Plot[f[y], {y, p[[1]] - .3, p[[1]] + 0.3}, PlotStyle -> Red,
Axes -> False, Frame -> True, ImageSize -> imgsz/3], {1.5, 3}]],
{{p, {0, 0}}, Locator, Appearance -> None}]
or, if you also want to place the inset interactively:
Manipulate[
Plot[f[x], {x, -3, 3}, PlotRange -> {{-3, 3}, {-2, 5}},
ImageSize -> imgsz,
Epilog ->
Inset[Plot[f[y], {y, p[[1, 1]] - .3, p[[1, 1]] + 0.3},
PlotStyle -> Red, Axes -> False, Frame -> True,
ImageSize -> imgsz/3], p[[2]]]],
{{p, {{0, 0}, {1.5, 3}}}, Locator, Appearance -> None}]
EDIT
one more alternative based on dbjohn's question:
imgsz = 400;
f[x_] := Piecewise[{{Sin#x, Abs#x > .1}, {Sin[100 x], Abs[x] <= 0.1}}];
Manipulate[
Plot[f[x], {x, -3, 3}, PlotRange -> {{-3, 3}, {-2, 5}},
ImageSize -> imgsz,
Epilog ->
Inset[Plot[f[y], {y, p[[1]] - .3, p[[1]] + 0.3}, PlotStyle -> Red,
Axes -> False, Frame -> True, ImageSize -> imgsz/3],
Scaled[zw]]], {{p, {0, 0}}, Locator,
Appearance -> None}, {{zw, {0.5, 0.5}, "Zoom window"}, Slider2D}]
Just a kickstart:
imgsz = 400;
f[x_] := Piecewise[{{Sin#x, Abs#x > .1}, {Sin[100 x], Abs[x] <= 0.1}}];
Plot[f[x], {x, -3, 3}, PlotRange -> {{-5, 5}, {-5, 5}},
ImageSize -> imgsz, Epilog ->
Inset[Plot[f[y], {y, -.3, 0.3}, PlotStyle -> Red, Axes -> False,
Frame -> True, ImageSize -> imgsz/3], {3, 3}]]
I find this an area in need of better built in tools. I have been working on this solution based on a demo here. I prefer to have the zoomed image and unzoomed image separated and as a bonus I added a presentable area where one could put relevant text or equations. For different functions the aspect ratio may need to be tweaked manually.
(f[x_] := x^2;
; xMin = -5; yMin = -5; xMax = 5; yMax = 5;
Manipulate[
Grid[{{LocatorPane[{a},
Plot[f[x], {x, xMin, xMax},
PlotRange -> {{xMin, xMax }, {yMin, yMax}},
ImageSize -> Medium, AspectRatio -> 1, AxesOrigin -> {0, 0}]],
Plot[f[x], {x, (a[[1]]) + xMin*mag, (a[[1]]) + xMax*mag},
PlotRange -> {{(a[[1]]) + xMin*mag, (a[[1]]) +
xMax*mag}, {(a[[2]]) + yMin*mag, (a[[2]]) + yMax*mag}},
ImageSize -> Medium, AspectRatio -> 1, AxesOrigin -> {0, 0}],
Item[StringForm["This is a suitable area to put any text.
Value of A is :
`1` ", a], Alignment -> {Left, Top}]}}, Frame -> All,
ItemSize -> All,
Spacings -> 5], {{a, {0, 0}}, {xMin, yMin}, {xMax, yMax}, Locator,
Appearance ->
Graphics[{Yellow, Opacity[.2],
Rectangle[Scaled[{.5 - (mag/2), .5 - (mag/2)}],
Scaled[{.5 + (mag/2), .5 + (mag/2)}]]}]}, {{mag, .5,
"Magnification"}, 0.01, 1, Appearance -> "Labeled"}])
(f[x_] :=
Piecewise[{{Sin#x, Abs#x > .1}, {Sin[100 x], Abs[x] <= 0.1}}];
; xMin = -3; yMin = -3; xMax = 3; yMax = 3;
Manipulate[
Grid[{{LocatorPane[{a},
Plot[f[x], {x, xMin, xMax},
PlotRange -> {{xMin, xMax }, {yMin, yMax}},
ImageSize -> Medium, AspectRatio -> 1, AxesOrigin -> {0, 0}]],
Plot[f[x], {x, (a[[1]]) + xMin*mag, (a[[1]]) + xMax*mag},
PlotRange -> {(*{(a[[1]])+xMin*mag,(a[[1]])+xMax*
mag},*){(a[[2]]) + yMin*mag, (a[[2]]) + yMax*mag}},
ImageSize -> Medium, AspectRatio -> 1, AxesOrigin -> {0, 0},
Frame -> True],
Item[StringForm["This is a suitable area to put any text.
Value of A is :
`1` ", a], Alignment -> {Left, Top}]}}, Frame -> All,
ItemSize -> All,
Spacings -> 5], {{a, {0, 0}}, {xMin, yMin}, {xMax, yMax}, Locator,
Appearance ->
Graphics[{Yellow, Opacity[.2],
Rectangle[Scaled[{.5 - (mag/2), .5 - (mag/2)}],
Scaled[{.5 + (mag/2), .5 + (mag/2)}]]}]}, {{mag, .06,
"Magnification"}, 0.01, 1, Appearance -> "Labeled"}])