Skip to content

"plot.ts" doesn't respect the value of "pch" (+ blocked from Bugzilla signups)

6 messages · Gregory Werbin, David Winsemius, Martin Maechler

#
I did a search on Bugzilla for "plot.ts" and didn't find anything on 
this issue. I tried to sign up for Bugzilla to report it, but my e-mail 
address didn't pass your "syntax checking" for a legal e-mail address.

The bug is easily reproducible on my machine as follows:

## start

# generate some data
y <- arima.sim(list(), 150)

# this will definitely dispatch to a ".ts" method
class(y)[1] == 'ts'

# compare and note that `cex = 0.5` has no effect
plot(y, type = 'b', pch = 16)
plot(y, type = 'b', pch = 16, cex = 0.5)

# it works if `y` is coerced back to a regular vector
plot(as.numeric(y), type = 'b', pch = 16, cex = 0.5)

# another way to see the issue
plot.ts(y, type = 'b', pch = 16, cex = 0.5)
plot.default(y, type = 'b', pch = 16, cex = 0.5)

## end

Skimming through source code for `plot.ts`, it seems like the `cex` 
argument is being "eaten" by a `...` somewhere without being properly 
passed to `plot.default`.

The output of `R.version` is:
platform       x86_64-apple-darwin15.5.0
arch           x86_64
os             darwin15.5.0
system         x86_64, darwin15.5.0
status
major          3
minor          3.1
year           2016
month          06
day            21
svn rev        70800
language       R
version.string R version 3.3.1 (2016-06-21)
nickname       Bug in Your Hair

Greg
#
'...' does not "eat" parameters, it passes them on.

Looking at the very top of the body we see this in the definition of the internal `plotts` function:

        cex = par("cex"), lty = par("lty"), lwd = par("lwd"), 
        axes = TRUE, frame.plot = axes, ann = par("ann"), cex.lab = par("cex.lab"), 
        col.lab = par("col.lab"), font.lab = par("font.lab"), 
        cex.axis = par("cex.axis"), col.axis = par("col.axis"), 

And at the end of the body we se the call to plotts (including the "dots")

So I would suggest using par-settings.


par(cex=0.5)
plot(y, type = 'b', pch = 16)


(Question seems more appropriate for r-help.)
#

        
>> On Aug 24, 2016, at 5:59 PM, Gregory Werbin <greg.werbin at libertymail.net> wrote:
>> 
    >> I did a search on Bugzilla for "plot.ts" and didn't find anything on this issue. I tried to sign up for Bugzilla to report it, but my e-mail address didn't pass your "syntax checking" for a legal e-mail address.

If you read (and you should :-)
   https://www.r-project.org/bugs.html
you will see the reason for the "syntax checking".
We currently need manual white listing (of e-mail addresses),
because we had months of "spam" bug reports and then complete
spam explosion aka "bug site devastation" action.

I have added your e-mail (above) to be valid / legal...
Please "subscribe", because we will not keep that changed string for so long.

[ Actually, I'd tend to say that for short term, we are now
  looking for volunteers for "bugzilla moderation".... ]


    >> 
    >> The bug is easily reproducible on my machine as follows:
    >> 
    >> ## start
    >> 
    >> # generate some data
    >> y <- arima.sim(list(), 150)
    >> 
    >> # this will definitely dispatch to a ".ts" method
    >> class(y)[1] == 'ts'
    >> 
    >> # compare and note that `cex = 0.5` has no effect
    >> plot(y, type = 'b', pch = 16)
    >> plot(y, type = 'b', pch = 16, cex = 0.5)
    >> 
    >> # it works if `y` is coerced back to a regular vector
    >> plot(as.numeric(y), type = 'b', pch = 16, cex = 0.5)
    >> 
    >> # another way to see the issue
    >> plot.ts(y, type = 'b', pch = 16, cex = 0.5)
    >> plot.default(y, type = 'b', pch = 16, cex = 0.5)
    >> 
    >> ## end
    >> 
    >> Skimming through source code for `plot.ts`, it seems like the `cex` argument is being "eaten" by a `...` somewhere without being properly passed to `plot.default`.

    > '...' does not "eat" parameters, it passes them on.

    > Looking at the very top of the body we see this in the definition of the internal `plotts` function:

    > cex = par("cex"), lty = par("lty"), lwd = par("lwd"), 
    > axes = TRUE, frame.plot = axes, ann = par("ann"), cex.lab = par("cex.lab"), 
    > col.lab = par("col.lab"), font.lab = par("font.lab"), 
    > cex.axis = par("cex.axis"), col.axis = par("col.axis"), 

    > And at the end of the body we se the call to plotts (including the "dots")

    > So I would suggest using par-settings.

    > par(cex=0.5)
    > plot(y, type = 'b', pch = 16)

as a workaround, yes, thank you David!

    > (Question seems more appropriate for r-help.)

Still, I would tend to think that it was reasonable feature
request to ask for  plot.ts() to be improved there,  and then
R-devel or the R-bugzilla would be ok, too.

Martin Maechler, ETH Zurich


    > -- 
    > David.
    >> 
    >> The output of `R.version` is:
    >> platform       x86_64-apple-darwin15.5.0
    >> arch           x86_64
    >> os             darwin15.5.0
    >> system         x86_64, darwin15.5.0
    >> status
    >> major          3
    >> minor          3.1
    >> year           2016
    >> month          06
    >> day            21
    >> svn rev        70800
    >> language       R
    >> version.string R version 3.3.1 (2016-06-21)
    >> nickname       Bug in Your Hair
    >> 
    >> Greg
    >> 
    >> ______________________________________________
    >> R-devel at r-project.org mailing list
    >> https://stat.ethz.ch/mailman/listinfo/r-devel

    > David Winsemius
    > Alameda, CA, USA

    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel
#
I've had a chance to read the source more thoroughly. The chain of 
events is as follows:

1. Local function `plotts()` is defined with argument `cex` that 
defaults to `par("cex")`
2. `...` is passed to `plotts()`. If "cex" is an element in `...`, 
inside `plotts()` the variable `cex` is assigned thereby (overriding the 
default arg). Importantly, this means that the element "cex" is captured 
and _removed_ from `...`. `...` is eventually passed to `plot.window()`.
3.
   - In the univariate case (NCOL(x) == 1): When `lines.default()` is 
called to actually plot the data 
(https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L588 
and 
https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L597 
for reference), `cex` is not included in the call.
   - In the bivariate case (NCOL(x) > 1): Because "cex" was captured and 
removed from `...`, it is not passed to `plot.default` when it is called 
(https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L548).

It turns out that the "eating" is not being done by `...` but by the 
signature of `plotts`.

The documentation currently reads:
This, to me, suggests parity with the 'plot' function in how the 
arguments in '...' are handled. Therefore either the code is wrong or 
the documentation is incomplete and misleading.

I filed this is as a bug because it's undocumented, and inconsistent 
with how other arguments typically passed through `plot.default` are 
handled.

I'll be happy to do the patch myself -- I just need to know which thing 
to patch (the source or the docs).


Greg
On 2016-08-25 03:00, David Winsemius wrote:

            
#
> I've had a chance to read the source more thoroughly. The chain of 
    > events is as follows:

    > 1. Local function `plotts()` is defined with argument `cex` that 
    > defaults to `par("cex")`
    > 2. `...` is passed to `plotts()`. If "cex" is an element in `...`, 
    > inside `plotts()` the variable `cex` is assigned thereby (overriding the 
    > default arg). Importantly, this means that the element "cex" is captured 
    > and _removed_ from `...`. `...` is eventually passed to `plot.window()`.
    > 3.
    > - In the univariate case (NCOL(x) == 1): When `lines.default()` is 
    > called to actually plot the data 
    > (https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L588 
    > and 
    > https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L597 
    > for reference), `cex` is not included in the call.
    > - In the bivariate case (NCOL(x) > 1): Because "cex" was captured and 
    > removed from `...`, it is not passed to `plot.default` when it is called 
    > (https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L548).

    > It turns out that the "eating" is not being done by `...` but by the 
    > signature of `plotts`.

    > The documentation currently reads:

    >> ...: additional graphical arguments, see 'plot', 'plot.default' and 
    >> 'par'.

    > This, to me, suggests parity with the 'plot' function in how the 
    > arguments in '...' are handled. Therefore either the code is wrong or 
    > the documentation is incomplete and misleading.

the code is not perfect aka "wrong" .. so the bug is there.
Making the minimal reproducible example more concise,

 plot(as.ts((-10:12)^3), type="b", cex=.5)
 plot(     ((-10:12)^3), type="b", cex=.5)

should plot identically ... but currently don't


    > I filed this is as a bug because it's undocumented, and inconsistent 
    > with how other arguments typically passed through `plot.default` are 
    > handled.

    > I'll be happy to do the patch myself -- I just need to know which thing 
    > to patch (the source or the docs).

[yes... and please subscribe to bugzilla which I told you
 yesterday I had explicitly opened for you !]

Martin
 
    > Greg
> On 2016-08-25 03:00, David Winsemius wrote:
>>> On Aug 24, 2016, at 5:59 PM, Gregory Werbin
>>> <greg.werbin at libertymail.net> wrote:
>>> 
    >>> I did a search on Bugzilla for "plot.ts" and didn't find anything on 
    >>> this issue. I tried to sign up for Bugzilla to report it, but my 
    >>> e-mail address didn't pass your "syntax checking" for a legal e-mail 
    >>> address.
    >>> 
    >>> The bug is easily reproducible on my machine as follows:
    >>> 
    >>> ## start
    >>> 
    >>> # generate some data
    >>> y <- arima.sim(list(), 150)
    >>> 
    >>> # this will definitely dispatch to a ".ts" method
    >>> class(y)[1] == 'ts'
    >>> 
    >>> # compare and note that `cex = 0.5` has no effect
    >>> plot(y, type = 'b', pch = 16)
    >>> plot(y, type = 'b', pch = 16, cex = 0.5)
    >>> 
    >>> # it works if `y` is coerced back to a regular vector
    >>> plot(as.numeric(y), type = 'b', pch = 16, cex = 0.5)
    >>> 
    >>> # another way to see the issue
    >>> plot.ts(y, type = 'b', pch = 16, cex = 0.5)
    >>> plot.default(y, type = 'b', pch = 16, cex = 0.5)
    >>> 
    >>> ## end
    >>> 
    >>> Skimming through source code for `plot.ts`, it seems like the `cex` 
    >>> argument is being "eaten" by a `...` somewhere without being properly 
    >>> passed to `plot.default`.
    >> 
    >> '...' does not "eat" parameters, it passes them on.
    >> 
    >> Looking at the very top of the body we see this in the definition of 
    >> the internal `plotts` function:
    >> 
    >> cex = par("cex"), lty = par("lty"), lwd = par("lwd"),
    >> axes = TRUE, frame.plot = axes, ann = par("ann"), cex.lab = 
    >> par("cex.lab"),
    >> col.lab = par("col.lab"), font.lab = par("font.lab"),
    >> cex.axis = par("cex.axis"), col.axis = par("col.axis"),
    >> 
    >> And at the end of the body we se the call to plotts (including the 
    >> "dots")
    >> 
    >> So I would suggest using par-settings.
    >> 
    >> par(cex=0.5)
    >> plot(y, type = 'b', pch = 16)
    >> 
    >> (Question seems more appropriate for r-help.)
    >> 
    >> --
    >> David.
    >> 
    >>> The output of `R.version` is:
    >>> platform       x86_64-apple-darwin15.5.0
    >>> arch           x86_64
    >>> os             darwin15.5.0
    >>> system         x86_64, darwin15.5.0
    >>> status
    >>> major          3
    >>> minor          3.1
    >>> year           2016
    >>> month          06
    >>> day            21
    >>> svn rev        70800
    >>> language       R
    >>> version.string R version 3.3.1 (2016-06-21)
    >>> nickname       Bug in Your Hair
    >>> 
    >>> Greg
    >>> 
    >>> ______________________________________________
    >>> R-devel at r-project.org mailing list
    >>> https://stat.ethz.ch/mailman/listinfo/r-devel
    >> 
    >> David Winsemius
    >> Alameda, CA, USA

    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel
#
>> I've had a chance to read the source more thoroughly. The chain of 
    >> events is as follows:

    >> 1. Local function `plotts()` is defined with argument `cex` that 
    >> defaults to `par("cex")`
    >> 2. `...` is passed to `plotts()`. If "cex" is an element in `...`, 
    >> inside `plotts()` the variable `cex` is assigned thereby (overriding the 
    >> default arg). Importantly, this means that the element "cex" is captured 
    >> and _removed_ from `...`. `...` is eventually passed to `plot.window()`.
    >> 3.
    >> - In the univariate case (NCOL(x) == 1): When `lines.default()` is 
    >> called to actually plot the data 
    >> (https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L588 
    >> and 
    >> https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L597 
    >> for reference), `cex` is not included in the call.
    >> - In the bivariate case (NCOL(x) > 1): Because "cex" was captured and 
    >> removed from `...`, it is not passed to `plot.default` when it is called 
    >> (https://github.com/wch/r-source/blob/trunk/src/library/stats/R/ts.R#L548).

    >> It turns out that the "eating" is not being done by `...` but by the 
    >> signature of `plotts`.

    >> The documentation currently reads:

    >>> ...: additional graphical arguments, see 'plot', 'plot.default' and 
    >>> 'par'.

    >> This, to me, suggests parity with the 'plot' function in how the 
    >> arguments in '...' are handled. Therefore either the code is wrong or 
    >> the documentation is incomplete and misleading.

    > the code is not perfect aka "wrong" .. so the bug is there.
    > Making the minimal reproducible example more concise,

    > plot(as.ts((-10:12)^3), type="b", cex=.5)
    > plot(     ((-10:12)^3), type="b", cex=.5)

    > should plot identically ... but currently don't

And there are more (such) problems,
E.g, lty, and lwd are not propagated, in the (x,y) case,

 plot.ts(as.ts(1:300), cumsum(rnorm(300)), type = "b", cex = 0.5, lwd = 2)

and also not in the "multiple" / matrix case.

I will commit a fix to  R-devel in a moment... but would be glad
for a careful review.

Martin