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]
Related
So I have a set of bounded diophantine equations that specify lines on the plane. I want to make mathematica plot the intersection of two of these equations so I can see what they look like.
So far I have something like:
Solve[0 < x - y < 3 && -1 < 2 x - y < 2, {x, y}, Integers]
which returns some structure like:
{{x -> -2, y -> -4}, {x -> -1, y -> -3}, {x -> -1, y -> -2}, {x -> 0,
y -> -1}}
but how can I now make mathematica plot this so I can see the resulting shape. Preferably I would like the plot to consider every 'point' to be a 1x1 square.
Also, I wonder if there is a better way to do such things. Thanks.
Define the data you wish to plot by transforming the list Solve[] returns. This can done as
data = {x, y} /. Solve[0 < x - y < 3 && -1 < 2 x - y < 2, {x, y}, Integers]
More generally, you can make Solve return the solution in a list format (rather than as a set of rules) using the following trick:
data = Solve[0 < x - y < 3 && -1 < 2 x - y < 2, {x, y}, Integers] /. Rule[a_,b_]->b
For plotting, among many alternatives, you can use ListPlot as
ListPlot[data, PlotMarkers -> {Style["\[FilledSquare]", FontSize -> 16]}]
to get the following output
You can further refine it using many styling and other options of ListPlot. For example, you can join the points
ListPlot[data, PlotMarkers -> {Style["\[FilledSquare]", FontSize -> 16]},
Joined -> True]
to get
EDIT: To play with the marker placement and size there are several alternatives. Using ListPlot you can get what you need in either of the two ways:
(* 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}
In both cases, you need to use Epilog, otherwise the lines joining points are occluded by the markers. Both alternatives produce the following output:
Alternatively, you can use Graphics, RegionPlot, ContourPlot, BubbleChart with appropriate transformations of data to get results similar to the one in ListPlot output above.
Using Graphics primitives:
(* 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}
Using 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}
Using 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}
Using 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}
may be
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}]
Can also extract the points to plot using
{#[[1, 2]], #[[2, 2]]} & /# sol
Please consider the following, from the followings from
Can we generate "foveated Image" in Mathematica
Clear[acuity];
acuity[distance_, x_, y_, blindspotradius_] :=
With[{\[Theta] = ArcTan[distance, Sqrt[x^2 + y^2]]},
Clip[(Chop#Exp[-Abs[\[Theta]]/(15. Degree)] - .05)/.95,
{0,1}] (1.-Boole[(x + 100.)^2 + y^2 <= blindspotradius^2])]
Plot3D[acuity[250., x, y, 9], {x, -256, 256}, {y, -256, 256},
PlotRange -> All, Axes -> False, PlotPoints -> 40,
ExclusionsStyle -> Automatic, Boxed -> False, Mesh -> None]
How could I add the photo below on the X & Y plane. Then have the surface plotted transparent.
Is it possible ? (image obtained with a solution in the question mentioned above).
i = Import["http://i.stack.imgur.com/0EizO.png"];
p = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
Show#{
Plot3D[
acuity[250., x, y, 9], {x, -256, 256}, {y, -256, 256},
PlotRange -> All, PlotPoints -> 40,ExclusionsStyle -> Automatic,Axes -> False,
Boxed -> False, Mesh -> None, PlotStyle -> Directive[Opacity[0.5]]],
Graphics3D[{Texture[i],
Polygon[Join[#, {0}] & /# (2 p - 1) 256, VertexTextureCoordinates -> p]}
]}
Edit
Dealing with AspectRatio[], as requested in your comments:
p = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
r = First##/Last## &#Dimensions#ImageData#i;
a = 1.4;
Show#{Plot3D[
acuity[250., a x, a y, 9], {x, -256 , 256 }, {y, -256 r , 256 r },
PlotRange -> All, PlotPoints -> 40, ExclusionsStyle -> Automatic,
Axes -> False, Boxed -> False, Mesh -> None,
PlotStyle -> Directive[Opacity[0.5]], AspectRatio -> r],
Graphics3D[{Texture[i],
Polygon[{{-256 , -256 r, 0}, { 256 , -256 r , 0},
{ 256 , 256 r, 0}, {-256 , 256 r, 0}},
VertexTextureCoordinates -> p]}]}
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"}])
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)