When plotting many aspects of a dataset in a single graph, it is often convenient to be able to hide all lines and then only selectively enable those that are of interest. The attached patch makes 'c' a keyboard shortcut for doing this in wxterminal.
The patch currently adds a case to wxtPanel::OnKeyDownChar for handling this. In the long term, a better solution might be to dispatch a command like "hide line 1" to the main gnuplot process, which then triggers a replot, but then there first has to be a way of targeting a command to a specific line.
Patch has been tested against the latest CVS version on Arch Linux x64.
Also submitted as a pull request on GitHub: https://github.com/gnuplot/gnuplot/pull/1
Modified patch that will actually set the lines to hidden, not just invert the hidden value.
How is this different or preferable to the current mechanism of toggling the lines on/off by clicking on the corresponding key entry?
When plotting graphs with a substantial number of lines, having to click each key entry quickly becomes tedious. For example when plotting data from experiments where you would preferably plot a lot of data by default just to see if something sticks out, but then if nothing seems out of the ordinary, you'll hide most of the lines and focus on only a few.
For example, for a set of experiments I'm currently running, I frequently plot graphs with 20+ lines, but I usually only focus on 2-4 at the time. Having to hide the 20 others one by one is very annoying. See http://jon.tsp.io/share/gnuplot-23-lines.png for an example.
Fair enough.
I think that if we're going to add something like this, it should be
via a mechanism that applies to all terminals, not just wxt. I
would suggest writing a generalized internal function toggle_all()
that flips the current on/off state of all plots in the graph. Then
one could bind this to whatever key you like
bind all "alt-c" builtin-toggle-all
Yeah, that is what I meant by the second paragraph in the initial post. I wasn't aware that gnuplot keeps an on/off state per plot in the graph? From what I can tell from the code, wxt keeps its own state to track whether a particular plot is visible or not?
I don't have a lot of experience with the gnuplot codebase, so the following might be way off, but presumably this would entail adding state to the gnuplot core for tracking whether a particular plot is to be shown or not. And then code would have to be added to each terminal that supports hiding/showing lines to sync any such changes with that state somehow. This would again mean we have to implement a "set visible <plot-id> true/false" command, where plot-id specifies which plot should be shown/hidden. That would increase the size of the patch quite significantly. Also, the format of plot-id would have to be determined as I don't think there are currently any gnuplot commands that target only a single plot?
I haven't given a lot of thought to it, but I think the mechanism would be to have the core code send a "toggle everything" request to the terminal, which would then be responsible for modifying whatever internal state variables it needs to. The request could be implemented via a new terminal entry point, or perhaps it could piggyback on an existing terminal entry point, for example term->layer(TERM_LAYER_TOGGLE_ALL)
So far as implementing this for the wxt terminal is concerned, the main difference from your original patch would be that the trigger would come in through a terminal call, e.g. wxt_layer(), not through wxtPanel::OnKeyDownChar()
Ah, okay, so only provide a "hide all" command, not a "hide a specific plot" command. I'll try coding it up and submit a new patch.
On Wed, Aug 7, 2013 at 2:34 PM, Jon Gjengset jonhoo@users.sf.net wrote:
Fair enough.
I think that if we're going to add something like this, it should be
via a mechanism that applies to all terminals, not just wxt. I
would suggest writing a generalized internal function toggle_all()
that flips the current on/off state of all plots in the graph. Then
one could bind this to whatever key you like
bind all "alt-c" builtin-toggle-all
Two thoughts:
1. I'm looking at adding a hide_plots function to the terminal interface, but the README says quite clearly that adding new interfaces should be an exceptional thing. Would you say it is appropraite in this case, or is piggybakcing on another existing function better?
2. What would be preferable, a function that toggles the visibility of all plots, or one that simply clears the plot? They have slightly different use cases. For me the latter is more useful, but I can see that the former could also be good to have in some scenarios.
Attached is a patch which:
Let me know what you think.
Here is a more generic implementation which:
Last edit: Jon Gjengset 2013-08-08
Attached is an updated patch that merges cleanly against 1.4526
Resolved merge conflict in ChangeLog
I tried to test this, but all I get is an immediate crash if I hit one of the hot-keys. The screen output is
OK. Got it. You need to synchronize the refresh call with a mutex:
Ah, nice catch! I think that might then also be needed in wxt_check_for_toggle(). Strange how the code worked without the mutex on my machine...
Attached patch has the following changes:
- Added mutex around cairo_refresh call
- s/toggle/invert/, and changed hotkey for inverting from 't' to 'i'
- Made 'v' show all and 'V' hide all (used to be the other way around)
- Fixed a bug that caused show all to behave like invert
- Made modify_plots take an unsigned int instead of an int (not strictly necessary, but makes more sense for a bit field)
Note that the ChangeLog entry still says 2013-08-08. Don't know if you want to change that or not?
Maybe. I'll double check. It may be that that check happens in the same thread that executes the display list, so no interlock is necessary. Anything from the command line definitely executes in a different thread.
What platform are you running on?
Linux x64
Don't worry about the ChangeLog entry.
Your patch is causing me to think again about how plots should be tracked for toggling. As long as the only mechanism for toggling was to click on the key entry, it made sense for only plots with a key entry to be tracked. Since your patch is now opening up the possibility of toggling plots from the command line, I'm thinking that maybe it would be better to create a visibility flag for all plots, whether or not they have a key entry. Then we could introduced a command "toggle 3" or "toggle all" or "toggle 4-6,8" that would do the same thing as clicking on the corresponding key entries except that wouldn't actually have to be a key entry.
Before accepting your patch
I'd like to think some more about the above. This may or may not affect the patch much.
It should support at least 2 terminals in addition to wxt. This might, for instance, show that it would be good to have an additional parameter for term->modify_plots(). Window number? graph number (in a multiplot)? Other people can help with this.
"modify plot" sounds more general than "toggle visibility". Are there other plot modifications that you had in mind, or could imagine? Again this might suggest additional parameters to the call in order to provide more flexibility.
Yeah, that was my thinking in a comment further up somewhere too. It would probably increase the size and complexity of the change quite a bit though.
I'll have a look at adding this to 2 more terminals. qt and x11 are the two other I can think of that are interactive?
The other ones currently are canvas, svg, and win
canvas and svg aren't interactive though?
They don't react to keypresses ('g' does not work for example), nor can I see how you could in an svg?
Both svg and canvas are interactive in that they respond to mouse clicks, and both support toggling the plots on/off. Canvas also responds to hot-keys, although the necessary HTML wrapper to enable them is unfortunately browser-dependent. Actually, the svg standard says it can do hotkeys, but gnuplot doesn't currently include code to support them.
Because the hotkey support for canvas is somewhat problematic, I usually provide a separate icon for, e.g., toggling the grid. You can see how this works in any of the demos with a grid, including the one on the top page of the demo site.
Somewhere near the top of my project list is a near total re-write of the .js code supporting the canvas terminal. Among other things it can be made to use the key entries as a toggle, just like the other terminals, in addition to using a separate icon. The point is that it's trivial to write a small .js routine to toggle the state of all plots. It can then be hooked to an icon or mouse event or hot key or whatever.
But yeah, neither svg nor canvas can do anything in response to commands on the gnuplot command line once they are being displayed.
Hmm, but in order to keep the bindings in sync (that is, respect the bindings set in gnuplot), the canvas code would then have to parse the table of bindings to figure out which key is bound to the various modplot actions, which seems brittle at best, no? With wxt and qt, this is handled through communication with the gnuplot core.
I could easily write up some js to show/hide plots in response to the same keys that are set by default, but dynamically discovering the bindings might not be quite so trivial.