2

Mathematica

DynamicModule[{list = {}}, 
 EventHandler[
  Dynamic[Framed@
    Graphics[{BSplineCurve[list], Red, Line[list], Point[list]}, 
     PlotRange -> 2]], {{"MouseClicked", 
     1} :> {AppendTo[list, 
      MousePosition["Graphics"]]}}, {"MouseClicked", 2} :> 
   Print[list]]]

I want to do the above at home where I do not have Mathematica. Use whatever tool you want, I like to use Python and R but happy with any solution candidate. The first thing that came to my mind was RStudio and this question here but I am unsure whether some better way to do this.

How can I do the interactive-GUI-innovating over X?

Procedure of the Mathematica -snippet outlined

1. you click points

2. you will see BSplineCurve formating between the points and points are red

3. points are saved to an array

4. when finished, you click `right-mouse-button` so array to stdout
Community
  • 1
  • 1
hhh
  • 50,788
  • 62
  • 179
  • 282
  • ?getGraphicsEvent has some features. As well, one can use RGtk2 (others too) for more event handling. – jverzani Aug 22 '12 at 17:54
  • 1
    I don't know Mathematica, but maybe `?locator` in R? – GSee Aug 22 '12 at 17:54
  • @GSee can you explain how the `locator` and `identify` work in R? Perhaps with an example? Even though I read the manuals, I cannot understand the -- tried to find examples such as [here](http://www.statmethods.net/advgraphs/interactive.html) but struggling with them, some firing NullPointException etc. – hhh Aug 22 '12 at 18:16
  • The best I can do is: `library(quantmod); getSymbols("SPY"); chartSeries(SPY); zooom()` Then click two places on the chart, and it will zoom in based on where you clicked. So, examine the source of `zooom` – GSee Aug 22 '12 at 18:22

3 Answers3

5

Here is an R function that does what you describe:

dynmodfunc <- function() {
    plot(0:1,0:1,ann=FALSE,type='n')
    mypoints <- matrix(ncol=2, nrow=0)
    while( length(p <- locator(1, type='p', col='red')) ) {
        mypoints <- rbind(mypoints, unlist(p))
        plot(mypoints, col='red', ann=FALSE, xlim=0:1, ylim=0:1)
        if(nrow(mypoints)>1) {
            xspline(mypoints, shape=-1)
        }
    }
    mypoints
}

(out <- dynmodfunc())

You can change the shape argument to xspline to change the style of spline. This version returns a 2 column matrix with the x and y values, but that could be changed to another structure if prefered. There are plenty of other things that could be customized as well.

Added function to get the output to paste into Mathematica:

matrix2mathematica <- function(x) {
    paste0( '{', 
        paste0( '{', x[,1], ', ', x[,2], '}', collapse=', '),
    '}')
}

cat( matrix2mathematica(out))
Greg Snow
  • 48,497
  • 6
  • 83
  • 110
  • 1
    Holy interactive, Batman! it even extends splines outside the plot area. And it allows crossing lines and all manner of amusement. Should be named spline.doodler(). – IRTFM Aug 22 '12 at 19:19
  • ...still the encoding left, this `str(['{'+str(x)+'.'+str(y)+'}' for x,y in zip(range(5,10),range(5))]).replace("'","")` is how I would do it in Python, `apply` to rewrite the `list-comprehension` or some ready encoding -function? – hhh Aug 22 '12 at 19:57
  • For people trying to do this with list-comprehension -style, you should check this thread [here](http://stackoverflow.com/questions/8745972/rewrite-this-list-comprehension-in-r), trying... paste -thing is though quite cool and elegant, looked like I tried to reinvent the wheel. For some reason when I think about string -concatenation like here, I tried to traverse things, here more direct. – hhh Aug 22 '12 at 20:16
1

Feel free to look at / take from my dorky, buggy, RateSketch() function in R, which does something similar here. You can pare it down to your case, plenty of room for simplification

hhh
  • 50,788
  • 62
  • 179
  • 282
tim riffe
  • 5,651
  • 1
  • 26
  • 40
1

Just a simple example of locator:

plot(1:10)
point <- locator(1)
# now click somewhere on the plot

point
$x
[1] 8.010256

$y
[1] 7.980781

(results will of course vary depending on where you clicked)

GSee
  • 48,880
  • 13
  • 125
  • 145
  • +1 this I can understand, takes some time to do something meaninful with it, Mathematica returned a nice Array like `{{1,2}, {3.2,3.1}, ...}`. – hhh Aug 22 '12 at 18:42