Related
I would like to highlight the fit region in a mathematica graph with appropriate fit error bar on it. To plot some data with error bar I write for example:
data={{{0, 0.00126517235028},
ErrorBar[0.0097546177348]}, {{1, 0.0132870239578},
ErrorBar[0.00717311242327]}, {{2, 0.00968907928987},
ErrorBar[0.0125454440978]}, {{3, 0.00835906062474},
ErrorBar[0.0196027916911]}, {{4, 0.0141038637039},
ErrorBar[0.0288324766544]}, {{5, 0.0467626302256},
ErrorBar[0.0423090450838]}, {{6, 0.0832535249208},
ErrorBar[0.0609066442506]}};
ErrorListPlot[p0all67, Frame -> True,
PlotRange -> {{0, 6}, {0.3, -0.04}}, Axes -> False,
PlotStyle -> {AbsolutePointSize[10], AbsoluteThickness[2]}]
Now I fit the data in anther software using linear fit method and for example, the fit result(or slope) in x=4 to x=6 is 0.0317349, and error bar is 0.0215005. I would like to highlight the fit region with this fit value and the error. So i expect the graph to look something like this:
Could anybody please help me how to do this? Thanks.
Needs["ErrorBarPlots`"];
data = {{{0, 0.00126517235028},
ErrorBar[0.0097546177348]}, {{1, 0.0132870239578},
ErrorBar[0.00717311242327]}, {{2, 0.00968907928987},
ErrorBar[0.0125454440978]}, {{3, 0.00835906062474},
ErrorBar[0.0196027916911]}, {{4, 0.0141038637039},
ErrorBar[0.0288324766544]}, {{5, 0.0467626302256},
ErrorBar[0.0423090450838]}, {{6, 0.0832535249208},
ErrorBar[0.0609066442506]}};
elp = ErrorListPlot[data, Frame -> True,
PlotRange -> {{0, 6}, {-0.05, 0.18}}, Axes -> False,
PlotStyle -> {AbsolutePointSize[7], AbsoluteThickness[1]},
PlotRangePadding -> {0.4, 0}];
m = 0.0317349;
line[x_, c_] := m x + c;
{x4, y4} = data[[5, 1]];
ytest = line[x4, 0];
c = y4 - ytest;
check = line[x4, c];
x6 = 6;
y6 = line[x6, c];
delta = 0.0215005;
a = {{x4, y4 + delta}, {x6, y6 + delta}};
b = {{x4, y4 - delta}, {x6, y6 - delta}};
Show[elp,
ListLinePlot[{{x4, y4}, {x6, y6}}, PlotStyle -> Thick],
ListLinePlot[{a, b}, Filling -> {1 -> {2}}, PlotStyle -> None],
ImageSize -> 500]
Here is also an example based on your data demonstrating some statistics functions.
data = {0.00126517235028, 0.0132870239578, 0.00968907928987,
0.00835906062474, 0.0141038637039, 0.0467626302256, 0.0832535249208};
lm = LinearModelFit[data, {1, x , x^2, x^3}, x];
{sd1, sd2} = 2*(CDF[NormalDistribution[0, 1], #] - 0.5) & /# {1, 2};
intervals = Flatten[Transpose /# Table[
lm["SinglePredictionConfidenceIntervals", ConfidenceLevel -> cl],
{cl, {sd1, sd2}}], 1];
{bands68[x_], bands95[x_]} = Table[
lm["SinglePredictionBands", ConfidenceLevel -> cl], {cl, {sd1, sd2}}];
Show[ListPlot[data, PlotMarkers -> Automatic], ListPlot[intervals],
Plot[{lm[x], bands68[x], bands95[x]}, {x, 5, 8}, Filling -> {2 -> {1}, 3 -> {2}}],
PlotRange -> {{1, 7}, {-0.02, 0.1}}, ImageSize -> 480, Frame -> True, Axes -> False]
How to specify separate alignments for the first column (excluding first row in this column), first row (excluding first element in this row) and all other elements in the Grid? It is preferable to do this just with Alignment option of Grid preserving tight control given by Item[] with Alignment option for more tight purposes.
P.S. This question comes from previous question but I wish to get individual control over alignments of horizontal and vertical table headings here.
I have found several ways to achieve what I want. The most direct solution is:
Grid[Table[Row#(Range[a]), {a, 1, 4}, {7}],
Alignment -> {Right,
Automatic, {{{2, -1}, {1, 1}} -> Left, {{1, 1}, {2, -1}} ->
Center}}, Dividers -> {{2 -> True}, {2 -> True}}]
Other solutions include:
Grid[Table[Row#Range[a], {a, 1, 4}, {7}],
Alignment -> {{Left, {Right}},
Automatic, {{1, 1}, {1, -1}} -> Center},
Dividers -> {{2 -> True}, {2 -> True}}]
Grid[Table[Row#Range[a], {a, 1, 4}, {7}],
Alignment -> {Right,
Automatic, {1 -> Left, {{1, 1}, {2, -1}} -> Center}},
Dividers -> {{2 -> True}, {2 -> True}}]
Grid[Table[Row#Range[a], {a, 1, 4}, {7}],
Alignment -> {Right,
Automatic, {1 -> Left, {{1, 1}, {1, -1}} -> Center}},
Dividers -> {{2 -> True}, {2 -> True}}]
Grid[Table[Row#Range[a], {a, 1, 4}, {7}],
Alignment -> {Right,
Automatic, {{{1, 1}, {1, -1}} -> Center, 1 -> Left}},
Dividers -> {{2 -> True}, {2 -> True}}]
It looks like Alignment uses the same syntax as the Background in Grid so it might help to look at Options > Background in the documentation for Grid for examples.
For example, suppose you want to align the item in the first row and first column top-right and all other items bottom-left, you could do something like
Grid[RandomInteger[10, {5, 5}], ItemSize -> {3, 3}, Frame -> All,
Alignment -> {Left, Bottom, {{1, 1} -> {Right, Top}}}]
If I understand your requirements, I would favor doing this with Item as follows:
x = Array[\[HappySmiley] &, {5, 5}];
x = ReplacePart[x,
i : Except[{1, 1}, {_, 1} | {1, _}] :>
Item[x~Extract~i, Alignment -> Left]
];
Grid[x, ItemSize -> {3, 3}, Frame -> All]
Say I have three lists: a={1,5,10,15} b={2,4,6,8} and c={1,1,0,1,0}. I want a plot which has a as the x axis, b as the y axis and a red/black dot to mark 1/0. For. e.g. The coordinate (5,4) will have a red dot.
In other words the coordinate (a[i],b[i]) will have a red/black dot depending on whether c[i] is 1 or 0.
I have been trying my hand with ListPlot but can't figure out the options.
I suggest this.
a = {1, 5, 10, 15};
b = {2, 4, 6, 8};
c = {1, 1, 0, 1};
Graphics[
{#, Point#{##2}} & ###
Thread#{c /. {1 -> Red, 0 -> Black}, a, b},
Axes -> True, AxesOrigin -> 0
]
Or shorter but more obfuscated
Graphics[
{Hue[1, 1, #], Point#{##2}} & ### Thread#{c, a, b},
Axes -> True, AxesOrigin -> 0
]
Leonid's idea, perhaps more naive.
f[a_, b_, c_] :=
ListPlot[Pick[Transpose[{a, b}], c, #] & /# {0, 1},
PlotStyle -> {PointSize[Large], {Blue, Red}}]
f[a, b, c]
Edit: Just for fun
f[h_, a_, b_, c_, opt___] :=
h[Pick[Transpose[{a, b}], c, #] & /# {0, 1},
PlotStyle -> {PointSize[Large], {Blue, Red}}, opt]
f[ ListPlot,
Sort#RandomReal[1, 100],
Sin[(2 \[Pi] #)/100] + RandomReal[#/100] & /# Range[100],
RandomInteger[1, 100],
Joined -> True,
InterpolationOrder -> 2,
Filling -> Axis]
Here are your points:
a = {1, 5, 10, 15};
b = {2, 4, 6, 8};
c = {1, 1, 0, 1};
(I deleted the last element from c to make it the same length as a and b). What I'd suggest is to separately make images for points with zeros and ones and then combine them - this seems easiest in this situation:
showPoints[a_, b_, c_] :=
With[{coords = Transpose[{a, b}]},
With[{plotF = ListPlot[Pick[coords, c, #], PlotMarkers -> Automatic, PlotStyle -> #2] &},
Show[MapThread[plotF, {{0, 1}, {Black, Red}}]]]]
Here is the usage:
showPoints[a, b, c]
One possibility:
ListPlot[List /# Transpose[{a, b}],
PlotMarkers -> {1, 1, 0, 1} /. {1 -> { Style[\[FilledCircle], Red], 10},
0 -> { { Style[\[FilledCircle], Black], 10}}},
AxesOrigin -> {0, 0}]
Giving as output:
You could obtain similar results (to those of Leonid) using Graphics:
Graphics[{PointSize[.02], Transpose[{(c/. {1 -> Red, 0 -> Black}),
Point /# Transpose[{a, b}]}]},
Axes -> True, AxesOrigin -> {0, 0}]
What is a good way to draw a smooth curve with specified starting and ending point and restricted to be inside of a piecewise linear tube like below?
(source: yaroslavvb.com)
coords = {1 -> {0, 2}, 2 -> {1/3, 1}, 3 -> {0, 0},
4 -> {(1/3 + 2)/2, 1}, 5 -> {2, 1}, 6 -> {2 + 1/3, 0},
7 -> {2 + 1/3, 2}};
gp = GraphPlot[graph, VertexCoordinateRules -> coords];
pr = {{-1, 3 + 1/3}, {-1 - 1/6, 3 + 1/6}};
scale = 50;
is = -scale*(Subtract ### pr);
lineThickness = 2/3;
graph = {1 -> 2, 3 -> 2, 2 -> 4, 4 -> 5, 5 -> 6, 5 -> 7};
path = {3, 2, 4, 5, 7};
lp = Graphics[{Blue, Opacity[.5],
AbsoluteThickness[lineThickness*scale], Line[path /. coords]}];
Show[lp, gp, PlotRange -> pr, ImageSize -> is]
Perhaps something like this:
coords = {2 -> {1/3, 1}, 1 -> {0, 0}, 3 -> {(1/3 + 2)/2, 1},
4 -> {2, 1}, 5 -> {2 + 1/3, 2}};
pr = {{-1, 3 + 1/3}, {-1 - 1/6, 3 + 1/6}};
scale = 50;
is = -scale*(Subtract ### pr);
lineThickness = 2/3;
graph = {1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5};
gp = GraphPlot[graph, VertexCoordinateRules -> coords];
path = {1, 2, 3, 4, 5};
f = BezierFunction[
SortBy[coords /. Rule[x_, List[a_, b_]] -> List[a, b], First]];
pp = ParametricPlot[f[t], {t, 0, 1}];
lp = Graphics[{Blue, Opacity[.5],
AbsoluteThickness[lineThickness*scale], Line[path /. coords]}];
Show[pp, lp, gp, PlotRange -> pr, ImageSize -> is]
You may gain a better control over the path by adding/removing control points for the Bezier. As I remember "A Bspline is contained in the convex hull of its control points", so you can add control points inside your thick lines (up and down the middlepoints in actual point set, for example) to bound the Bezier more and more.
Edit
The following is a first try to bound the curve. Bad programming, just to get the feeling of what can be done:
coords = {2 -> {1/3, 1}, 1 -> {0, 0}, 3 -> {(1/3 + 2)/2, 1},
4 -> {2, 1}, 5 -> {2 + 1/3, 2}};
pr = {{-1, 3 + 1/3}, {-1 - 1/6, 3 + 1/6}};
scale = 50;
is = -scale*(Subtract ### pr);
lineThickness = 2/3;
graph = {1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5};
gp = GraphPlot[graph, VertexCoordinateRules -> coords];
path = {1, 2, 3, 4, 5};
kk = SortBy[coords /. Rule[x_, List[y_, z_]] -> List[y, z],
First]; f = BezierFunction[kk];
pp = ParametricPlot[f[t], {t, 0, 1}, Axes -> False];
mp = Table[{a = (kk[[i + 1, 1]] - kk[[i, 1]])/2 + kk[[i, 1]],
Interpolation[{kk[[i]], kk[[i + 1]]}, InterpolationOrder -> 1][
a] + lineThickness/2}, {i, 1, Length[kk] - 1}];
mp2 = mp /. {x_, y_} -> {x, y - lineThickness};
kk1 = SortBy[Union[kk, mp, mp2], First]
g = BezierFunction[kk1];
pp2 = ParametricPlot[g[t], {t, 0, 1}, Axes -> False];
lp = Graphics[{Blue, Opacity[.5],
AbsoluteThickness[lineThickness*scale], Line[path /. coords]}];
Show[pp, pp2, lp, gp, PlotRange -> pr, ImageSize -> is]
Edit 2
Or perhaps better yet:
g1 = Graphics[BSplineCurve[kk1]];
Show[lp, g1, PlotRange -> pr, ImageSize -> is]
This one scales quite well when you enlarge the image (the previous ones don't)
Suppose I have the following results:
a=FindInstance[2*b^2 + b^3 == b^4 + t && t < 10 && t > -1, {b, t},
Integers, 20]
{{b -> -1, t -> 0}, {b -> 0, t -> 0}, {b -> 1, t -> 2}, {b -> 2,
t -> 0}}
How can I get rid of the "b->" and just get the array of b answers? I can get halfway there with:
a[[All,1]]
{b -> -1, b -> 0, b -> 1, b -> 2}
but how can I get to just:
{-1, 0, 1, 2}
Thanks
I might be missing something from dreeves' answer, but the way I always believed you do this was simply by writing:
b /. a
There is an example of this in the "Basic Examples" section of the documentation for the Solve function, which uses the same output style.
Though Will's answer is the canonical way to do it, I'll provide a few alternatives just for fun.
In[37]:= ans={{b -> -1, t -> 0},{b -> 0, t -> 0},{b -> 1, t -> 2},{b -> 2, t -> 0}};
In[38]:= Cases[ans, (b -> a_) :> a, Infinity]
Out[38]= {-1, 0, 1, 2}
In[39]:= ans[[All, 1]][[All, 2]]
Out[39]= {-1, 0, 1, 2}
In[40]:= ans /. {b -> a_, _} :> a
Out[40]= {-1, 0, 1, 2}
In[41]:= (ans /. Rule -> List)[[All, 1, 2]]
Out[41]= {-1, 0, 1, 2}