4
$\begingroup$

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}];

ListPlot[Tooltip@{Flatten[
     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.


EDIT 2:

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?

$\endgroup$
1
  • 2
    $\begingroup$ 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. $\endgroup$
    – m_goldberg
    Sep 3, 2015 at 15:18

2 Answers 2

6
$\begingroup$

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

screenshot

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.

$\endgroup$
4
  • $\begingroup$ This is an elegant answer. I think it would even more elegant with toolRule = Tooltip[x__] :> PopupWindow[Tooltip[x], popupGraph @ #2&[x]]; $\endgroup$
    – m_goldberg
    Sep 4, 2015 at 2:07
  • $\begingroup$ 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. $\endgroup$
    – Chromatic
    Sep 7, 2015 at 15:53
  • $\begingroup$ Can you give an example of the type of graph you want to show at each point? $\endgroup$
    – Jens
    Sep 7, 2015 at 16:56
  • $\begingroup$ I put an example in the question, which is the same way I use in my work. $\endgroup$
    – Chromatic
    Sep 7, 2015 at 19:49
2
$\begingroup$

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}}]

popup

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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