Interactive ListPlot by mouse clicking



Say I have a list of 2-tuples that is visualized by ListPlot. Each 2-tuple is also associated with another graph. Now what I want to realize is to display the corresponding graph by mouse-clicking "roughly" on the data point of the 2-tuple on the ListPlot plot.

I have found a similar question, but here I have ListPlot instead of BarChart. So it is not straightforward to use Button, as each data point has to be distinguished, but I do not know how to put Button on every point or whether it is a good idea to do so since there are hundreds of points.

Edit 1:

Regarding performance.

Sample code:

graphGen[x_, y_] := ListPlot[Table[{x - i^2 y, x + i y}, {i, 0, 30}]]

BulkCode = Table[indexedGraphVariable[x, y] = graphGen[x, y], {x, -10., 10, 
    1}, {y, -10., 10, 1}];

popupGraph[pt_] := indexedGraphVariable @@ pt

toolRule = Tooltip[x__] :> PopupWindow[Tooltip[x], popupGraph@Last@{x}];

     Table[{x, y}, {x, -2, 10, 1}, {y, -10, 10, 1}], 1], 
    Flatten[Table[{x, y}, {x, -10, -1, 1}, {y, -10, 10, 1}], 1]}, 
  ImageSize -> 1000] /. toolRule
  1. run the code
  2. open the system monitor, notice the memory used by MMA, which should be static, like 70MB
  3. click up ten popup windows and close them, check the memory again. It starts going up gradually until ~500MB
  4. if re-do the process, the used memory gets doubled

This code plots only 400 points. If there are ~10000 points, the popup-window clicking will cost several GB, and the interface slows down obviously.


The problem emerges actually when I try to click on the point but miss clicking on the background of the ListPlot graph. The interface then starts to get slow. I suppose this is due to ToolTip's underlying mechanism but do not know how?


Posted 2015-09-03T14:59:14.090

Reputation: 764


You should look atClickPane. If you give your list plot as the first argument, the action function in the second argument with get the point that was clicked on in plot coordinates. You can write the action function to find the nearest pair in your list of data pairs and use the found pair to select the what you want to display.

– m_goldberg – 2015-09-03T15:18:38.760



Here is a simple way to convert any ListPlot into something that raises a PopupWindow, and it gives you feedback about the active point before clicking it, by showing a Tooltip:

popupGraph[pt_] := 
 Graphics[Circle[pt, .1], PlotRange -> {{0, 4}, {0, 4}}, Frame -> True]

toolRule = 
  Tooltip[x__] :> PopupWindow[Tooltip[x], popupGraph@Last@{x}];

ListPlot[Tooltip@{{1, 2}, {2, 3}, {3, 1}}] /. toolRule


Here I made up a Graphics to show in the popup that takes the coordinate of the listed point as the center of a circle.

The idea is to start with regular Tooltips and replace them after the execution of ListPlot, using the replacement toolRule. I used the same idea in this answer.


Posted 2015-09-03T14:59:14.090

Reputation: 93 191

This is an elegant answer. I think it would even more elegant with toolRule = Tooltip[x__] :> PopupWindow[Tooltip[x], popupGraph @ #2&[x]]; – m_goldberg – 2015-09-04T02:07:36.203

There is a downside of speed and memory. I have a list of more than 10000 tuples. With popup plain text it is fast. But with popup graphs it really slows down quite a lot and consumes several Gbs of RAM. I guess it tries to store all the popup graphs in advance instead of calculating them on the fly. Anyway it is a great answer already. If there is a way to improve the performance I will be much delighted. – Chromatic – 2015-09-07T15:53:14.237

Can you give an example of the type of graph you want to show at each point? – Jens – 2015-09-07T16:56:28.833

I put an example in the question, which is the same way I use in my work. – Chromatic – 2015-09-07T19:49:01.800


Not as nice as Jens answer since it doesn't give the identifying tooltip, but is does have a certain simplicity.

popup[pt_] := 
  Graphics[Circle[pt, .1], PlotRange -> {{0, 4}, {0, 4}}, Frame -> True]
ListPlot[PopupWindow[#, popup[#]]& /@ {{1, 2}, {2, 3}, {3, 1}}]



Posted 2015-09-03T14:59:14.090

Reputation: 104 223