0
$\begingroup$

As I said before for the time being, I don't want to use Mathematica as a programming tool. I'm just using it as a calculater to compute integrals, solve equations, etc because of its support of symbolic math.
So my question is not about adding zooming and panning capability to your code

As you know in 3D graphics (as far as I know graphics that are created by Plot3D function) we can use:

  • Click + Drag ---> Rotate
  • Alt + Click + Drag ---> Zoom in and out
  • Shift+Click+Drag ---> Pan

but for 2D graphics (as far as I know graphics that are created by Plot function) we don't have such capability.

I searched a bit on the net and in this site and found out that there are no built in plot manipulating interface in mathematica and I should use this code to be able to pan and zoom on 2D plots that I have created in notebook.
But I don't know how to use a certain piece of code and call a function in mathematica. I'm just starting to learn, so please pardon me if it's so trivial.

For example suppose that I have created this plot and now I want to be able to pan and zoom on it. What should I do?

Manipulate[
 Plot[PDF[VonMisesDistribution[μ, κ], x], {x, -Pi + μ, 
   Pi + μ}, PlotRange -> {{-5, 5}, {0, 20}}], {{μ, 0}, -5, 
  5}, {{κ, 5}, 0, 1000}]
$\endgroup$
10
  • $\begingroup$ What do you mean by "I don't know how to use a certain piece of code"? Are you talking about a specific piece of code or code in general? I assume by now you should have figured out how to run code. As to the specific question at the bottom of the post: just change the numbers in the x range to pan and the numbers in the PlotRange option to zoom. You can make those numbers parameters in the Manipulate as well. $\endgroup$ Commented Sep 15, 2015 at 21:26
  • 5
    $\begingroup$ @SjoerdC.deVries changing the numbers of 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 sentence I 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$ Commented Sep 15, 2015 at 21:45
  • $\begingroup$ @SjoerdC.deVries familiar with the interface of the function in the library. We call the functions in our code, pass parameters to them and get the output and use in our code. or in matlab if I want to use this ready function in my code, I just put the M-file of it in the same directory that my code is running. And I just call the functions in my code. My purpose is if we consider this code a ready package, how should $\endgroup$ Commented Sep 15, 2015 at 21:51
  • $\begingroup$ I use that ready functions in my code? $\endgroup$ Commented Sep 15, 2015 at 21:52
  • $\begingroup$ Just run the PlotExplorer code in that answer and you can use the PlotExplorer function as shown as in the examples in the post. The libraries you are looking for are called packages in Mathematica. You can read about them here. $\endgroup$ Commented Sep 15, 2015 at 21:59

2 Answers 2

2
$\begingroup$
Manipulate[
 Pane[
  Plot[Sin[x], {x, -10, 10}],
  ImageSize -> {300, 200},
  Scrollbars -> True,
  ScrollPosition -> {a, b}],
 {a, 10, 200},
 {b, 10, 200}]
$\endgroup$
1
  • $\begingroup$ Very nice. I wasn't aware of the Srollbars option. From this I can see that a "zoom" can also be added: Manipulate[ Pane[Plot[Sin[x], {x, -10, 10}, ImageSize -> zoom {600, 400}], ImageSize -> {300, 200}, Scrollbars -> True], {{zoom, 1, "Zoom"}, 0.1, 10}] $\endgroup$
    – JimB
    Commented Sep 16, 2015 at 13:38
1
$\begingroup$

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:

$\endgroup$
3
  • $\begingroup$ Would this thread then rather be a duplicate of the linked one? $\endgroup$
    – Yves Klett
    Commented Sep 16, 2015 at 9:42
  • $\begingroup$ @YvesKlett Yes, that is my opinion. $\endgroup$
    – dionys
    Commented Sep 16, 2015 at 9:48
  • $\begingroup$ @dionys I did what you said and flagged it as duplicate of that question after changing the title $\endgroup$ Commented Sep 16, 2015 at 9:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.