[rkward-devel] plot history featrues

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Tue Sep 7 09:04:43 UTC 2010


Hi,

overall this specification looks good to me. I do think there are some aspects 
which can safely be neglected for an initial implementation, however, in order 
not to introduce too much complexity too soon. I'll point out those, and add a 
few other comments.

On Tuesday 07 September 2010, Prasenjit Kapat wrote:
> A. a global history - all managed screen devices will share it.
> 
> B. ignore preview devices completely
> 
> C. a STATIC global switch (checkbox) to enable / disable the plot
> history feature. STATIC means: "toggling the checkbox will only affect
> new sessions of rkward, not the running ones"
> - this global switch should be used to enable/disable the menu/toolbar
> actions as well

Just an idea, haven't thought this through: Wouldn't it be enough to disable 
the record()-function (and clear any existing history) in order to effectively 
turn off the whole history? That could easily be switchable at runtime, then.

> Features:
> 
> 1. history length restriction
> 
> 2. duplicating a device:
> - behave as if the duplicated plot is "new" ie do not alter the old plot
> - when/if, possible to determine (reliably) that this "new" duplicated
> plot and old plot (duplicated from) are identical, do not save this
> new plot, otherwise always add it to the history at a new position

I'd say the second bullet can safely be neglected for an initial 
implementation. Then no special treatment should be needed for dev.copy() at 
all, as it will simply behave like any other new plot.

If we do go for hashes at a later point of time, no special treatment will be 
needed, either, as we can test for duplicates at any position in history very 
fast, then.

> 3. multiple plots on the screen:
> - check for par (mfig) and graphics:::.SSexists ("sp.screens")

While certainly desirable, this can probably be ignored for an intial 
implementation as well, IMO.

> 4. save the history list when rkward closes - not for this release
> - as part of the "save workspace"?
> - Windows uses .GlobalEnv::.savedPlots right from the beginning
> - when loading, replace the existing plot history by the loaded one?

Agreed, not for this release. For any R objects in the workspace, the policy 
is to remove those, and then add the new ones. So I guess the existing plot 
history would be replaced in this case, too.

Note that ?recordPlot cautions that "bad things may happen" if the plot was 
saved with another version of R. So we'd have to check for matching R version.

> 5. Actions:
> a. first / prev / next / last
> b. remove plot (has to be implemented due to 1.)
> c. append plot
> d. insert plot
> e. overwrite/replace plot (insert then remove)

Insert, then remove would certainly do the trick, but also it could have side-
effects of popping plots from history. So perhaps a separate treatment might 
make sense after all.

As long as "append plot" exists, "insert plot" can probably wait, too. So if 
insert seems complex, I suggest ignoring it for now.

> f. clear history
> g. plot properties
> 
> 5a. first / prev / next / last

(and plot.new()/dev.off())

> - always record
> - if the recorded version is not identical (see *1) to the old one and
> if the same plot is displayed on multiple devices, then save this
> recorded plot in place on the current device but set the status of the
> plots on all these "other" devices as "new"
> - if the number of these "other" devices > 1, then no way to avoid
> duplicated plots (err on the conservative side!) (see *2)
> 
> 5b. remove plot
> - if the user removes a plot from a device then replay the "next
> available" plot on this device

Add a special case when the plot is automatically removed due to history 
length restriction. In this case, the current device does not show the removed 
plot (but rather the one to be saved), and does not need to replay anything.

> - if this removed plot is displayed on any "other" device(s) then set
> their status to "new"
> - again, if after removal, more than one "other" device displays the
> removed plot, then set these as "new" - no reliable way to avoid
> duplicated plots in the history  (see *2)
> 
> 5c. append plot
> - no matter what the current status is, this action should always
> append the displayed plot to the history
> - this is a safe guard action, ie, if some plot does not pass through
> the plot.new / print.trellis etc. wrappers then the user still has a
> way to add it to the history w/o loosing the plot
> 
> 5d. Insert plot
> - similar to append, but the plot will be "inserted" in the history
> - care needs to be taken to avoid copying / moving the whole/part of
> the recorded history

See above. Not required for an initial implementation as long as "append plot" 
exists.

> 5e. Clear history
> - after clearing, make the plots displayed on the devices as "new"
> 
> 5f. Plot properties
> - for lattice calls, truncate the call string to a fixed length
> - additional status bar? since drop-down menu has been implemented,
> this may not be needed.
> - for graphics::: functions extract the last plot call from history,
> if at all possible - last priority, may not work at all
> 
> [*1]
> use either identical (a,b) or identical (a[[1]], b[[1]])

Are you sure the raw vector is not needed for comparison? But in fact, I could 
not find a counter-example so far.

Hm, I did a bit of timing, and it appears to make virtually no difference for 
the plots I've tried (in fact, for very small plots, identical(a, b) is 
faster, probably because the [[1]]-extraction takes some time, too):

> plot (rnorm (10000))
> a <- recordPlot()
> b <- recordPlot ()
> system.time (for (i in 1:10000) identical (a[[1]], b[[1]]))
   user  system elapsed 
 10.489   0.056  10.596 

> system.time (for (i in 1:10000) identical (a, b))
   user  system elapsed 
 10.481   0.036  10.481

> [*2]
> For plots saved via "a <- recordPlot ()" a[[1]] is all that is
> "sufficient" I think. It contains the data as well as the meta data.
> In that case, we can hash using digest (a[[1]]) and later (more?)
> reliably identify / track duplicated plots in the history? (Make
> digest a dependency of rkward or make it modular?)

The idea to use a hash is certainly appealing, but I'm also reluctant to add 
new hard dependencies. Using an optional dependency, sounds like adding a lot 
of complexity, though. Qt also supports MD5 and SHA1, so perhaps it's not too 
much trouble to cook a basic digest ourselves, instead. I'm not sure, how much 
impact this would have on the implementation. If it's just a detail, I'd say 
it's for a later release. If it's a core aspect, I'd say use digest() for now, 
and I'll look into creating hash function based on Qt.

Regards
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/rkward-devel/attachments/20100907/08f12793/attachment.sig>


More information about the Rkward-devel mailing list