[R] Lattice, ggplot, and pointsize

Milan Bouchet-Valat nalimilan at club.fr
Wed Jun 5 22:53:23 CEST 2013


Le mercredi 05 juin 2013 à 19:37 +0530, Deepayan Sarkar a écrit :
> On Sun, May 26, 2013 at 12:47 AM, Milan Bouchet-Valat <nalimilan at club.fr> wrote:
> > Le mardi 21 mai 2013 à 21:39 +0100, Prof Brian Ripley a écrit :
> >> On 21/05/2013 21:24, Bert Gunter wrote:
> >> > At the risk of misunderstanding... (inline)
> >> >
> >> > On Tue, May 21, 2013 at 12:17 PM, Milan Bouchet-Valat <nalimilan at club.fr> wrote:
> >> >> Le mardi 21 mai 2013 à 08:17 -0700, Jeff Newmiller a écrit :
> >> >>> That is like complaining that your hammer does not fit these
> >> >>> newfangled Philips screws.
> >> >>>
> >> >>> These are different tools. Do not expect them to interoperate.
> >> >> I understand that Lattice and ggplot2 do not use settings from par().
> >> >> I'm fine with this, as these packages are different from base graphics
> >> >> and have they own equivalent to tweak settings.
> >> >>
> >> >> What I do not understand is that one argument passed to output devices,
> >> >> which are _not_ provided by package graphics, is ignored by these two
> >> >> packages. Lattice and ggplot2 do not provide an alternative output
> >> >> system,
> >> >
> >> > False, I believe, depending on what you mean by "output system". They
> >> > both use grid graphics, not base graphics and with lattice, anyway,
> >>
> >> Indeed.  The issue is a design difference between the base and grid
> >> graphics subsystems.  See the 'R Internals' manual for more details.
> >
> > Thanks for the pointers. Indeed there is some interesting documentation
> > there. I've also had a deeper look at the code, and I've traced
> > pointsize (called ps) back to the R_GE_gcontext struct in
> > src/include/R_ext/GraphicsEngine.h.
> >
> > If I understand correctly, base graphics draw text using GText() in
> > src/library/graphics/src/graphics.c, which in turn calls GEText() in
> > src/main/engine.c. GEText() does take into account the pointsize.
> >
> > On the other hand, grid graphics draw text using gridText() from
> > src/library/grid/src/grid.c. This function uses gcontextFromgpar() to
> > get its R_GE_gcontext object. gcontextFromgpar() (defined in gpar.c)
> > computes the pointsize from the fontsize gpar setting and a general
> > scaling of the output:
> >     /*
> >      * Scale by GSS_SCALE (a "zoom" factor)
> >      */
> >     gc->ps = gpFontSize(gp, i) * REAL(gridStateElement(dd, GSS_SCALE))[0];
> >
> > What is interesting is that when a new device gets initialized by grid
> > (initGPar() atin gpar.c), the fontsize gpar settings is set to the
> > device starting pointsize:
> >     REAL(gpfs)[0] = dev->startps;
> >
> > And indeed this works with svg():
> >> svg("test.svg", pointsize=5)
> >> get.gpar("fontsize")
> > $fontsize
> > [1] 5
> >
> > ...but not with Lattice:
> >> trellis.par.get("fontsize")
> > $text
> > [1] 12
> >
> > $points
> > [1] 8
> >
> >
> > So the problem does not appear to be a base vs. grid graphics issue, but
> > rather something specific to Lattice and ggplot2. And indeed, when
> > looking at Lattice's sources, canonical.theme() in settings.R does:
> >              fontsize         = list(text = 12, points = 8),
> >
> > As simple as that! I didn't need to look so deep into the code... :-/
> >
> >
> > ?trellis.par.set says:
> >      The initial settings for each device defaults to values
> >      appropriate for that device. In practice, this boils down to three
> >      distinct settings, one for screen devices like ‘x11’ and
> >      ‘windows’, one for black and white plots (mostly useful for
> >      ‘postscript’) and one for color printers (color ‘postcript’,
> >      ‘pdf’). [This may not be up-to-date, though...]
> >
> > So it does not appear completely absurd to try to adjust to the device
> > settings where appropriate. Pointsize seems such a case to me.
> > canonical.theme() could set the text font size to get.gpar("fontsize").
> > Since the default value is 12 for most devices, this would not change
> > anything by default. (ggplot2 could probably benefit from a similar
> > change.)
> 
> If I remember correctly (it was a long time ago), I had nothing in
> particular against the default text fontsize. The default symbol size
> in grid was larger than I liked, and so fontsize$points was set to
> something more reasonable, and fontsize$text just seemed natural to
> add. It is only ever used in a single call to gpar() inside
> print.trellis. So it seems perfectly reasonable to take the default of
> fontsize$text from grid instead.
> 
> I don't like the idea of making the default
> 'get.gpar("fontsize")$fontsize' though, because that requires a device
> to be active, which canonical.theme() doesn't by design. Instead I
> have changed the default to NULL, and the fontsize is now set from (in
> order of priority)
> 
> 1. trellis.par.get("fontsize")$text  # NULL by default
> 2. trellis.par.get("grid.pars")$fontsize # NULL by default
> 3. get.gpars()$fontsize # approximately device pointsize by default
> 
> Hopefully this works for you. You can test using the r-forge version.
Thanks! I've just tested it and it seems to fix the problem. Your
solution indeed makes more sense. This nicely proves that grid graphics
can perfectly cooperate with output devices.

Do you think that symbol size could also adapt in the same way? It
sounds natural that the default the ratio between symbol size and text
size is constant disregarding the device's pointsize. To retain the
current default, it would mean that
points = 8/12 * text


Regards

> -Deepayan
> 
> > I realize this is no longer a discussion relevant for R as a whole, but
> > I am posting it here nevertheless in case somebody was interested. Maybe
> > we should discuss this offlist with Deepayan.
> 
> [...]



More information about the R-help mailing list