[Rd] palette() can hang and fail due to X11

Andrew Piskorski atp at piskorski.com
Fri Apr 25 20:55:22 CEST 2014

On Thu, Apr 24, 2014 at 09:22:40PM -0400, Simon Urbanek wrote:

> The bottom line is that you probably don't want to set the palette
> if you don't have a device that could be used.

Ok.  In my testing so far, it seems all I need is a simple little
function that does:

  pdf(); nn <- dev.cur(); rr <- palette(my.colors); dev.off(nn); rr 

I could have it check dev.list() and skip creating the sacrificial pdf
device if there already is a real graphics device up and running, but
in my testing so far that doesn't seem to be necessary, creating the
new pdf device gives the right behavior no matter what.

So if anybody else runs into this, that seems to be the practical
solution, it's pretty easy.  Pedantically though, ideally this hack
wouldn't be necessary.  You said:

> palette is a property recorded in the graphics device*

Perhaps its implementation currently is, I don't know.  (But what
about the special "null" graphics device that is always open,
shouldn't that be a good place to record the session-wide palette?)
But logically, the color palette is not and cannot be solely a
property of a graphics device.  Note that help("palette") says:

   There is only one palette setting for all devices in a R session. 
   If the palette is changed, the new palette applies to all 
   subsequent plotting. 

So the current color choices are logically a property of the R
session, independent of any specific graphics devices.

Clearly, palette() was always intended to do two things.  One, it
changes the user's session-wide default colors.  Two, it tells the
currently open graphics device (if any), to use those new colors.

A new (and no doubt useful) feature in R 3.0 is that each graphics
device remembers its history of palette changes.  Apparently as a side
effect of that change, palette() now INSISTS that a real non-null
graphics device be open, and opens one if there isn't.  This is a new
third thing palette() does that it never did before.

Glomming together all three of these essentially independent jobs into
the single palette() command seems a bit unfortunate.  Is there was
some way for me to do ONLY the first of palette()'s jobs, set my
session-wide default colors and that's it?  It looks like there is no
such entry point in the code, but the little hack with the sacrificial
pdf device above is a way to approximate one.

Andrew Piskorski <atp at piskorski.com>

More information about the R-devel mailing list