Why graphics::plot call on hexbin object throws an error? - r

In short: I'm trying to run this hexbin example which works fine unless I replace plot with graphics::plot. The latter throws following error:
> graphics::plot(bin, main="" , colramp=my_colors , legend=F )
Error in as.double(y) :
cannot coerce type 'S4' to vector of type 'double'
How to make this work?
Wider context why I need this work this way. I contribute to the clojisr project which brings R to Clojure using RServe. There is an option to require R packages and create corresponding Clojure functions. This works well (see this or this). The underlying calls to R are in the form of {package::symbol} for everything.

Class hexbin is an S4 class and the package defines an S4 generic and a method for plot. (The source code is here). There is no S4 generic for plot in the graphics package namespace, only an S3 generic.
The solution is therefore very simple:
hexbin::plot(bin, main="" , colramp=my_colors , legend=F )
Here's a reprex to prove it:
library(hexbin)
library(RColorBrewer)
# Create data
x <- rnorm(mean=1.5, 5000)
y <- rnorm(mean=1.6, 5000)
# Make the plot
bin<-hexbin(x, y, xbins=40)
my_colors=colorRampPalette(rev(brewer.pal(11,'Spectral')))
hexbin::plot(bin, main="" , colramp=my_colors , legend=F )
Created on 2020-02-17 by the reprex package (v0.3.0)

Related

ggmosaic: "Discrete value supplied to continuous scale" error when ggplot2/ggmosaic is imported

In my package, I like to create a mosaic plot. In the interactive session, this works well. However, if I call the function from an fresh R session with devtools::load_all, the error "Discrete value supplied to continuous scale" is raised.
Here is a minimum working example:
test_ggmosaic <- function(dat) {
dat <- datasets::mtcars
p <- ggplot2::ggplot(data=dat)+
ggmosaic::geom_mosaic(
ggplot2::aes(weight=mpg,x=ggmosaic::product(gear, cyl), fill=mpg)
) +
ggplot2::theme_bw()+
ggplot2::scale_fill_discrete(guide=ggplot2::guide_legend(reverse=TRUE)
)
return(p)
}
Now when this function is defined inside a package, and ggplot2 and ggmosaic are added to the Imports field in the DESCRIPTION file, and I call this function after loading devtools and (via load_all) the package the function is in, I get the error
Fehler: Discrete value supplied to continuous scale
When, on the other hand, I first execute
library(ggplot2)
library(ggmosaic)
and then call the function above, the plot appears (and does not make much sense in this example).

Creating plot using plotnine of python from R through reticulate

Being a R user, I am learning to incorporate python command in R through reticulate, I tried plotting graph using the plotnine package in R but it returned the following error, can anyone help?
library(reticulate)
library(ggplot2)
pd <- import('pandas', as='pd',convert=FALSE)
p9 <- import('plotnine')
mpg_py <- r_to_py(mpg,convert=FALSE)
mpg_pd <- pd$DataFrame(data=mpg_py)
p9$ggplot(data=mpg_pd,p9$aes(x='displ',y='cty'))
# Error in py_call_impl(callable, dots$args, dots$keywords) :
# AttributeError: 'NoneType' object has no attribute 'f_locals'
The answer to this question pointed me down a promising path for this error. It seems the error is due to an issue in the patsy package that handles the namespace/scoping for plotnine. By default the plotnine.ggplot constructor creates an environment to know where to get the plotting data and aesthetics. So adapting from the linked answer, here's a potential solution where we import the patsy package and use the environment parameter in the ggplot function to pass an evaluation environment (docs).
library(reticulate)
library(ggplot2)
pd = import('pandas',convert=F)
p9 = import('plotnine')
# new imports
patsy = import('patsy')
# import to be able to show in RStudio (see issue here: https://github.com/rstudio/rstudio/issues/4978)
matplotlib = import('matplotlib')
matplotlib$use('tkAgg')
plt = import('matplotlib.pyplot')
mpg_py <- r_to_py(mpg,convert=FALSE)
mpg_pd <- pd$DataFrame(data=mpg_py)
plot_py = p9$ggplot(mpg_pd,p9$aes(x='displ',y='cty'),
# new code (-1 was the only value that didn't throw an error)
environment = patsy$EvalEnvironment$capture(eval_env=as.integer(-1)))
print(class(plot_py)) # "plotnine.ggplot.ggplot" "python.builtin.object"
# Actually show the plot
plot_py
plt$show()

Unable to plot hclust object with ggtree

I am trying to plot a dendrogram from a hclust object with ggtree but I keep getting the same error message:
Error: `data` must be a data frame, or other object coercible by `fortify()`, not an S3 object with class hclust
I have been extensively looking for a solution, but found none. Furthermore, I have learned that ggtree does support hclust objects, which has confused me even more. From here:
The ggtree package supports most of the hierarchical clustering
objects defined in the R community, including hclust and dendrogram as
well as agnes, diana and twins that defined in the cluster package.
I have borrowed a reproducible example from the link above:
hc <- hclust(dist(mtcars))
p <- ggtree(hc, linetype='dashed')
Which, again, gives me the abovementioned error. If I use rlang::last_error() to get a bit of context, I get:
<error/rlang_error>
`data` must be a data frame, or other object coercible by `fortify()`, not an S3 object with class hclust
Backtrace:
1. ggtree::ggtree(hc, linetype = "dashed")
3. ggplot2:::ggplot.default(...)
5. ggplot2:::fortify.default(data, ...)
And if I use rlang::last_trace() to get a bit further information:
<error/rlang_error>
`data` must be a data frame, or other object coercible by `fortify()`, not an S3 object with class hclust
Backtrace:
x
1. \-ggtree::ggtree(hc, linetype = "dashed")
2. +-ggplot2::ggplot(...)
3. \-ggplot2:::ggplot.default(...)
4. +-ggplot2::fortify(data, ...)
5. \-ggplot2:::fortify.default(data, ...)
But I can really see what is wrong...
I have managed to solve my issue. I will post it in case it is of help for someone else in the future.
Apparently, I was running an older version of ggtree which was not beeing correctly updated when I reinstalled ggtree from Bioconductor, I am not sure why. Anyway, I tried to reinstall it by explicitly setting the version argument in the installation call:
BiocManager::install("ggtree", version = "3.10")
And then I could successfully run my reproducible example:
hc <- hclust(dist(mtcars))
p <- ggtree(hc, linetype='dashed')
Note that as a previous workaround, I had managed to plot the hcluster object with ggtree by transforming it to a phylo object with the as.phylo() function from the ape package:
hc <- hclust(dist(mtcars))
hc <- ape::as.phylo(hc)
p <- ggtree(hc, linetype='dashed')

Error when using "panel.ellipse" function in R

I want to draw a confidence ellipse. I search the R document and find the function: panel.ellipse. Here is the description website
Then I tried. I used the code below:
library(corrgram)
a<-c(1,2,3,4,5)
b<-c(2,4,6,5,3)
panel.ellipse(a, b)
But an error occur:
Error in plot.xy(xy.coords(x, y), type = type, ...) :
plot.new has not been called yet
I didn't call "plot.new", why did R say that?
You're linking to the latticeExtra::panel.ellipse function in the description link, but seem to be using corrgram which also has a panel.ellipse function. So I'm not sure which panel.ellipse function you are using/want to use.
From ?corrgram::panel.ellipse:
# CAUTION: The latticeExtra package also has a 'panel.ellipse' function
# that clashes with the same-named function in corrgram. In order to us
# the right one, the example below uses 'lower.panel=corrgram::panel.ellipse'.
# If you do not have latticeExtra loaded, you can just use
# 'lower.panel=panel.ellipse'.
Why not use ggplot2::stat_ellipse instead?
# Your sample data
a<-c(1,2,3,4,5)
b<-c(2,4,6,5,3)
df <- cbind.data.frame(a, b);
# Use stat_ellipse to draw confidence ellipse
require(ggplot2);
ggplot(df, aes(a, b)) + geom_point() + stat_ellipse();

Pesky ggplot2 namespace conflict when using ggplot2 in package

I'm contributing to the qmethod R package, and I just wrote a function that creates a bunch of ggplot2 objects.
The function works fine, but builds and R CMD Check warns me that:
replacing previous import by ‘ggplot2::%+%’ when loading ‘qmethod’
I've looked at SE posts and #hadley's book but can't figure out the problem.
Here's the relevant parts of my NAMESPACE:
import("ggplot2",
"stringr")
import("psych")
importFrom("plyr","count")
importFrom("reshape2","melt")
importFrom("digest", "digest")
importFrom("RColorBrewer", "brewer.pal")
And here's part of my DESCRIPTION:
Imports:
digest,
psych,
knitr,
RColorBrewer,
stringr,
ggplot2,
plyr,
reshape2
The part where I call a ggplot2 function inside my function array.viz.R looks like this (and more):
g <- ggplot(
data = array.viz.data
,aes(
x = fsc # factor scores, always same variable bc dataframe is constructed for every factor array by above loop
,y = ycoord # just the random ycoord for viz
,ymax = max(ycoord)
,ymin = 0
#,label = item.wrapped # this for some reason causes an error
)
)
g <- g + geom_tile( # add background tiles
aes(
fill = item.sd
)
)
Ps.: you can find the entire current work here: https://github.com/maxheld83/qmethod/tree/array-viz
Pps.: I am aware that ggplot2 itself imports a bunch of the functions I also import (such as reshape2), so I have a hunch that that might be a problem.
Turns out, import("psych") is the offending package.
It seems to somehow export again ggplot::%+%, though I can't think of why that would be the case.
Anyway, the fix is:
importFrom("psych", "principal") # that's the function we were using

Resources