The answer by @IstvánZachar that you linked seems to do all that you want and more:
Attributes[PlotExplorer] = {HoldFirst};
PlotExplorer[defPlot_] :=
DynamicModule[{held, head, plot, range, zoomRange, defRange,
defSize, defEpilog, size, pt1, pt2, spt1, dist, rect = {},
dragged = False, overButton = False, pushedButton = False,
overHor = False, overVer = False, activeHor = False,
activeVer = False, xPos = .5, yPos = .5, minDistance = 0.1,
sliderRatio = 0.05, panFactor = 10, reset, distance, slider,
replot, coord = None}, held = Hold@defPlot;
head = Part[held, 1, 0];
plot = defPlot;
{defEpilog, defRange} = {Epilog, PlotRange} /.
Quiet@AbsoluteOptions@plot;
defEpilog = defEpilog /. Epilog -> {};
size = defSize = Rasterize[plot, "RasterSize"];
range = zoomRange = defRange;
Deploy@
EventHandler[
Dynamic[MouseAppearance[
Show[plot, PlotRange -> Dynamic@range,
Epilog -> {defEpilog,(*Original epilog*)(*Replot button*)
EventHandler[
Inset[Graphics[{Black,
Dynamic@
Opacity@If[overButton, If[pushedButton, .2, .1], 0],
Rectangle[{0, 0}, {1, 1}, RoundingRadius -> Offset@5],
Black, Dynamic@
Opacity@If[overButton, If[pushedButton, .9, .7], 0],
Text["Replot", Center]}, ImageSize -> 50,
AspectRatio -> 1/2,
BaseStyle -> {FontFamily -> "Helvetica"}], Scaled@{1, 1},
Scaled@{1, 1}], {"MouseEntered" :> (overButton = True),
"MouseExited" :> (overButton = False),
"MouseDown" :> (pushedButton = True),
"MouseUp" :> (pushedButton = False;
replot@plot)}],(*Zoom rectangle*)
FaceForm@{Blue, [email protected]},
EdgeForm@{Thin, Dotted, [email protected]},
Dynamic@rect,(*Range sliders*)
Inset[slider[Dynamic@xPos, Dynamic@overHor,
Dynamic@activeHor, size, True], Scaled@{.5, 0},
Scaled@{.5, 0}],
Inset[slider[Dynamic@yPos, Dynamic@overVer,
Dynamic@activeVer, size, False], Scaled@{0, .5},
Scaled@{0, .5}]}],(*cursor*)
Which[dragged, "FrameRisingResize", CurrentValue@"AltKey",
Graphics[{Antialiasing -> False, Line@{{-1, 0}, {1, 0}},
Line@{{0, -1}, {0, 1}},
Dynamic@Text[
Style[coord, FontFamily -> "Helvetica", 8], {0,
0}, {-1.1, -1}]}, ImageSize -> 160, ImagePadding -> 0,
AspectRatio -> 1, PlotRange -> {{-1, 1}, {-1, 1}}*8],
CurrentValue@"ControlKey" && ! overHor && ! overVer,
"ZoomView", CurrentValue@"ShiftKey" && ! overHor && ! overVer,
"DragGraphics",
CurrentValue@"ShiftKey" && (overHor || overVer), "LinkHand",
True, Automatic]],
TrackedSymbols :> {dragged,
plot}], {"MouseMoved" :> (coord = MousePosition@"Graphics"),
"MouseClicked" :>
If[! overButton && CurrentValue@"MouseClickCount" == 2,
reset[]],
"MouseDown" :>
If[(! overHor || ! overVer), pt1 = MousePosition@"Graphics";
spt1 = MousePosition@"GraphicsScaled"],
"MouseDragged" :>
If[(! overHor && ! overVer || dragged) && ! overButton && !
pushedButton && ! activeVer && ! activeHor, dragged = True;
Which[CurrentValue@"ControlKey",
dist = Last@MousePosition@"GraphicsScaled" - Last@spt1;
range =
zoomRange*10^
dist,(*"GraphicsScaled" is required below as "Graphics" \
would give jumpy results as the plot range is constantly modified.*)
CurrentValue@"ShiftKey",
pt2 = MapThread[
Rescale, {MousePosition@
"GraphicsScaled", {{0, 1}, {0, 1}}, zoomRange}] - pt1;
range = zoomRange - pt2, True, pt2 = MousePosition@"Graphics";
rect = If[pt2 === None, {}, Rectangle[pt1, pt2]]]],
"MouseUp" :> (If[! CurrentValue@"ShiftKey" && !
CurrentValue@"ControlKey" && dragged &&
distance[pt1, pt2, zoomRange] > minDistance, rect = {};
range = Transpose@Sort@{pt1, pt2};]; zoomRange = range;
dragged = False)}, PassEventsDown -> True,
PassEventsUp -> True],
Initialization :> (slider[Dynamic[pos_], Dynamic[over_],
Dynamic[active_], size_, hor_] :=
EventHandler[
Dynamic[LocatorPane[
If[hor, Dynamic[{pos, .5}, (pos = Clip[First@#, {0, 1}];
range[[1]] =
If[CurrentValue@"ShiftKey",
First@zoomRange + (pos - .5)*
Abs[Subtract @@ First@zoomRange]*panFactor,
First@zoomRange*10^((pos - .5)*2)]) &],
Dynamic[{.5, pos}, (pos = Clip[Last@#, {0, 1}];
range[[2]] =
If[CurrentValue@"ShiftKey",
Last@zoomRange + (pos - .5)*
Abs[Subtract @@ Last@zoomRange]*panFactor,
Last@zoomRange*10^((pos - .5)*2)]) &]],(*Locator below \
is required inside Graphics as LocatorPane inside Inset looses the \
crosshair image.*)
Graphics[{Black,
Opacity@If[(over || active) && ! dragged, .1, 0],
Rectangle[{0, 0}, {1, 1}, RoundingRadius -> Offset@5],
Opacity@1,
Locator[Dynamic@If[hor, {pos, .5}, {.5, pos}],
Appearance ->
If[(over || active) && ! dragged, Automatic, None]]},
ImagePadding -> 0, PlotRangePadding -> 0,
ImageSize ->
If[hor, #*{1, 0} + {0, 20} &, #*{0, 1} + {20, 0} &]@size,
AspectRatio ->
If[hor, 1/sliderRatio/First@size, sliderRatio*Last@size]],
Enabled -> (over || active), Appearance -> None,
FrameMargins -> 0, ContentPadding -> False],
TrackedSymbols :> {pos, over, active,
dragged}], {"MouseDown" :> (active = True),
"MouseUp" :> (active = False),
"MouseEntered" :> (over = !
If[hor, activeVer,
activeHor]),(*The value of `active` must be public so \
that one slider can check whether the other is dragged,
not to pop up if the other locator is moved over this \
slider's area.*)"MouseExited" :> (over = False)},
PassEventsDown -> True];
replot[p_] :=
Module[{temp},
Switch[head, Plot,
temp = ReplacePart[
held, {{1, 2} -> {held[[1, 2, 1]], range[[1, 1]],
range[[1, 2]]}}];
(*Replace plot range or insert if nonexistent*)
plot = ReleaseHold@
If[MemberQ[temp, PlotRange, Infinity],
temp /. {_[PlotRange, _] -> (PlotRange -> range)},
Insert[temp, PlotRange -> range, {1, -1}]],
DensityPlot | ContourPlot | RegionPlot | StreamPlot |
StreamDensityPlot | VectorPlot | VectorDensityPlot |
LineIntegralConvolutionPlot,
temp = ReplacePart[
held, {{1, 2} -> {held[[1, 2, 1]], range[[1, 1]],
range[[1, 2]]}, {1, 3} -> {held[[1, 3, 1]],
range[[2, 1]], range[[2, 2]]}}];
plot =
ReleaseHold@
If[MemberQ[temp, PlotRange, Infinity],
temp /. {_[PlotRange, _] -> (PlotRange -> range)},
Insert[temp, PlotRange -> range, {1, -1}]];, _, Null]];
reset[] := (range = zoomRange = defRange; xPos = yPos = .5);
(*Quiet suppresses error message when Rescale[y,{x,
x}] where y\[NotEqual]x.EuclideanDistance then defaults to \
Infinity which is fine.*)
distance[p1_, p2_, {r1_, r2_}] :=
Quiet[N@EuclideanDistance[Rescale[p1, r1], Rescale[p2, r2]]];)];
Here is how you can run it on your plot:
dist1 /: PDF[dist1[a_, b_], x_] := Exp[b Cos[x - a]]/(2 \[Pi] BesselI[0, b])
PlotExplorer[Plot[PDF[dist1[0, 5], x], {x, -\[Pi] + 0, \[Pi] + 0}]]
How to use a certain piece of code and call a function
You don't need to learn all the intricacies of Mathematica all at once to use it, but you'll be confused and frustrated by many of the exact things that make Mathematica such an excellent tool if you don't spend a little time getting the basics down:
PlotRange
is one way. But I want to know if there is any built-in way as in Plot3D, some GUI interface that enables you to pan. The code here seems to be able to add this GUI to a 2D graphic. about the sentenceI don't know how to use a certain piece of code and call a function in mathematica.
: My purpose is that for example in C++ we have object oriented programming. We use 3rd party libraries and are not aware of their implementation. We are just $\endgroup$