I tried to plot a wordcloud with wordcloud2. As long as I just try to plot the words, everything works fine, but as soon as I try to shape the wordcloud with figPath/wordcloud2::lettercloud something goes wrong. To see the output, I have to run the function twice/reload it (I think this is a bug that has already been reported and discussed)
Additionally in my case it seems like I just plot the shape without the words ...
dat <- dplyr::tibble(word=c("A","B","C","D"),
n=c(10,1,50,12))
# works fine
wordcloud2::wordcloud2(dat)
# here I just see the shape
wordcloud2::wordcloud2(dat,figPath="data/test_shape.jpg")
# here I just see the letter
wordcloud2::letterCloud(dat,word="R")
Related
I'd like to display a plot and then have the user give some input, but the plot always appears after the input line. A simple example is:
plot( 1:10 )
ans <- readline("What is your favorite number?")
which gives the prompt first and then does the plot. The end goal will then be to do this in a for loop, where each iteration I present a plot and then ask the user for feedback about the plot.
This is in Colab and I'd like to stay working in Colab as this is an application for students and I want something they can run easily.
I've tried various things including Sys.sleep(0) and flush.console() but without any luck.
Edit My MWE above isn't actually representative of my code. A better example is the following:
par(mfrow=c(1,2))
plot(1:10)
plot(1:10)
print('Hello')
you could use plot.new():
This function (frame is an alias for plot.new) causes the completion of plotting in the current plot
plot( 1:10 )
plot.new()
ans <- readline("What is your favorite number?")
This is my code which is part of a larger script.
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
png(paste(survPath,"/surv_",d1,".png",sep=""))
plot(survfit1,xlab="Years",ylab="Survival probability",xmax=xmax1)
}
I don't have a good idea of what this code does yet, so I'm trying to look at each individual plot to see what it is. The problem is, whenever I run this in the R command line in the terminal in linux, nothing appears. I have to use dev.off() multiple times and then rerun this code:
plot(survfit1)
for something to appear. How can I see all the plots?
Sounds like this is really what you want:
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
x11() ## open up new graphical window for each plot (to avoid overwriting)
plot(survfit1,xlab="Years",ylab="Survival probability",
xmax=xmax1, main = d1) ## use different titles to distinguish those plots
}
This will produce plots on normal graphical windows.
If you want to use the original code, you'd better do this way:
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
png(paste(survPath,"/surv_",d1,".png",sep=""))
plot(survfit1,xlab="Years",ylab="Survival probability",xmax=xmax1)
dev.off()
}
Then, have a look at the directory given by getwd(). All the plots are saved in png files.
Calling Sys.sleep(.1) might help during the for loop. Maybe try:
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
Sys.sleep(.1)
png(paste(survPath,"/surv_",d1,".png",sep="", collapse="))
plot(survfit1,xlab="Years",ylab="Survival probability",xmax=xmax1)
dev.off()
}
How can I add vertical line to chart in quantmod that appears in the background? Consider this example:
library(quantmod)
symbol <- "AAPL"
cache <- new.env()
getSymbols(symbol, env=cache)
chartSeries(cache$AAPL, subset="last 3 months")
plot(addLines(v=10)) # Adds vertical line at tick 10.
The problem is that adding the vertical line at tick 10 now hides the wicks from the candlestick:
I also tried the function addVLine from qmao. It effectively does this:
c <- quantmod:::get.current.chob()
i <- index(c#xdata[endpoints(c#xdata, "months")])
plot(addTA(xts(rep(TRUE, length(i)), i), on=-1, col="grey"))
The result looks like this:
While I have the lines in the background now, they are super wide and pretty obtrusive. I just want them in the background in the same way the grid lines already exist there. How can I achieve this?
Note: this question resembles an existing one, but here I am asking on how to render the vertical line in the background.
I didn't look at the source code to understand why this works, but it seems to do what you want. Basically, you add the addLines call via the TA argument to chartSeries. This is generally a good thing to do anyway, since it avoids re-drawing the chart for each add* call.
chartSeries(cache$AAPL, subset="last 3 months", TA="addVo();addLines(v=10,on=-1)")
A lot of the time, I find it very useful to output graphics with pdf() as it allows me to scroll through pages and observe subtle differences (e.g. the page numbers may correspond to a particular parameter in a simulation).
Sometimes if the plot is quite packed with information, the fact that the PDF is a vector graphic means that it takes a long time to load in a PDF reader and is useless for scrolling through pages. I could plot with png(), but this would result in many image files.
My ideal solution would be to have a device that will plot a bitmap graphic (e.g. PNG) to a PDF.
I have read that cairo_pdf() outputs to a bitmap sometimes? Or I could write something that outputs to PNG, then combines these all together into a PDF?
Any other thoughts? Or does anyone have a solution for this already?
UPDATE: have now added method based on readPNG() as suggested in comments above. It's a bit slower (3s vs 9s) and seems to result in slightly larger file sizes than ImageMagick. rasterImage() interpolation makes no difference to filesize or timing, but alters the appearance slightly. If it's FALSE, then it looks the same as ImageMagick
I have just come up with the following solution using ImageMagick. It's not perfect, but it seems to work well so far.
png2pdf <- function(name=NULL,removepngs=TRUE,method="imagemagick",pnginterpolate=FALSE){
# Run the png() function with a filename of the form name%03d.png
# Then the actual plotting functions, e.g. plot(), lines() etc.
# Then dev.off()
# Then run png2pdf() and specify the name= argument if other pngs exist in the directory
# Need to incorporate a way of dealing with non-square plots
if(is.null(name)){
names <- list.files(pattern="[.]png")
name <- unique(sub("[0-9][0-9][0-9][.]png","",names))
if(length(name)!=1) stop("png2pdf() error: Check filenames")
}else{
names <- list.files(pattern=paste0(name,"[0-9][0-9][0-9][.]png"))
}
# Can change this to "convert" if it is correctly in the system path
if(method=="imagemagick"){
cmd <- c('C:\\Program Files\\ImageMagick-6.9.0-Q16\\convert.exe',names,paste0(name,".pdf"))
system2(cmd[1],cmd[-1])
}else if(method=="readPNG"){
library(png)
pdf(paste0(name,".pdf"))
par(mar=rep(0,4))
for(i in 1:length(names)){
plot(c(0,1),c(0,1),type="n")
rasterImage(readPNG(names[i]),0,0,1,1,interpolate=pnginterpolate)
}
dev.off()
}
if(removepngs) file.remove(names)
}
I'm trying to save a ggplot within a function using graphics devices. But I found the code produces empty graphs. Below is a very very simple example.
library(ggplot2)
ff <- function(){
jpeg("a.jpg")
qplot(1:20, 1:20)
dev.off()
}
ff()
If I only run the content of the function, everything is fine. I know that using ggsave() will do the thing that I want, but I am just wondering why jpeg() plus dev.off() doesn't work. I tried this with different versions of R, and the problem persists.
You should use ggsave instead of the jpeg(); print(p); dev.off() sequence. ggsave is a wrapper that does exactly what you intend to do with your function, except that it offers more options and versatility. You can specify the type of output explicitly, e.g. jpg or pdf, or it will guess from your filename extension.
So your code might become something like:
p <- qplot(1:20, 1:20)
ggsave(filename="a.jpg", plot=p)
See ?ggsave for more details
The reason why the original behaviour in your code doesn't worked is indeed a frequently asked question (on stackoverlflow as well as the R FAQs on CRAN). You need to insert a print statement to print the plot. In the interactive console, the print is silently execututed in the background.
These plots have to be printed:
ff <- function(){
jpeg("a.jpg")
p <- qplot(1:20, 1:20)
print(p)
dev.off()
}
ff()
This is a very common mistake.