15

The geom_density_ridges geom from the ggridges package created ridgelines, and if a bandwidth is not specified, it attempts to find a sensible value. It then uses the base R message function to report that value (see https://twitter.com/ClausWilke/status/921363157553172480).

The base R function suppressMessages function is designed to suppress such messages. For example, this code outputs a message:

message('This is a message');

And this code outputs nothing:

suppressMessages(message('This is a message'));

However, for some reason, the suppressing of messages seems, um, suppressed when this geom is added to a ggplot. The following code does still produce a message:

require('ggplot2');
require('ggridges');
suppressMessages(ggplot(Orange, aes(x=age,y=Tree)) + geom_density_ridges());

(Specifically, "Picking joint bandwidth of 319".)

Why is this? Does ggplot do something to ensure that messages come through regardless of the users' specification? Or is this actually sensible behavior that I just happen to not know about?

When generating RMarkdown reports, the chunk option message can be set to message=FALSE, which suppresses all messages at the rendering level. And since that's my use case, my problem is solved.

And as Claus Wilke, the author of the ggridges package, suggested, you can always set the bandwidth of manually to avoid the message (https://twitter.com/ClausWilke/status/921361195231215616).

But why doesn't suppressMessages suppress the message in the first place?

Is this expected behavior that I just happen to not know about?

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104
Matherion
  • 657
  • 1
  • 5
  • 13
  • I noticed in the documentation it states `suppressMessages evaluates its expression in a context that ignores all ‘simple’ diagnostic messages.` I wonder if the key term here is *simple*... – Dan Oct 20 '17 at 14:01
  • 4
    If you manually call `print` instead of letting the interpreter take care of that for you then `suppressMessages` does suppress the messages. `suppressMessages(print(ggplot(Orange, aes(x=age,y=Tree)) + geom_density_ridges()))` At one point I understood this process a little better (how messages get passed and how suppressMessages works and all that) but I've long since forgotten some of the details so am looking forward to an actual response explaining the 'why'. – Dason Oct 20 '17 at 14:11
  • 5
    @Dason I think you got it. The messages aren't generated till you call `print()` on the object. If you just type a variable in the R console, R implicitly calls `print()` on that object and shows the result. If you you run `supressMessages(ggplot(...))`, that's really the same as `print(supressMessages(ggplot(...)))` and there are no messages generated during building. You need `supressMessages(print(ggplot(...)))` to silence those during printing. – MrFlick Oct 20 '17 at 14:20
  • Ah, that's it! So calling the `ggplot(...)` statement does not print anything yet; `ggplot` just returns the resulting object, which is then accepted by `suppressMessages` and passed on, where R calls the associated `print` method which then triggers the `message`s. By forcing this `print` call to occur within the `suppressMessages` context, the printing of the `message`s is indeed suppressed. That actually makes sense. So this would qualify as a 'Why' in my book - if you change your comment to an answer, I'll accept it. Or we wait for more, whatever you prefer :-) – Matherion Oct 20 '17 at 14:57

1 Answers1

11

When you call ggplot(), that command doesn't actually draw a plot -- it creates a ggplot object. Only when that object is printed is a plot actually drawn. When you type an expression in the R console, the default behavior is to call print() on the result which is why it seems like ggplot() draws a plot.

Note that the warnings you are experiencing do not occur during the creation of the ggplot object; they occur during the printing of this object. So if you run

suppressMessages(ggplot(...))

that's essentially the same as

print(suppressMessages(ggplot(...)))

when running R in interactive mode. But since no messages are generated by ggplot(), nothing is suppressed and those messages still appear when the resulting object is printed. To suppress the messages created during printing, you need to wrap the actual print() statement with suppressMessages().

suppressMessages(print(ggplot(...)))
MrFlick
  • 195,160
  • 17
  • 277
  • 295