Add vertical line in background in quantmod chart - r

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)")

Related

wordcloud2: shape covers words

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")

bokeh: How to export a grid to png with given size?

I prepared some bokeh plots to display as html.
To this end I prepared a gridplot containing the subplots, the legends and some headings. This all displays extremely nice in HTML and with sizing_mode='stretch_width' it's even kind of responsive.
webpage = gridplot([[header_col],[panel_grid_plot]], toolbar_location=None, sizing_mode='stretch_width')
show(webpage)
Now I also want to export this "webpage" to a PNG. To this end, I use
export_png(webpage, filename= png_filename, width=1800)
Unfortunately, the width parameter is ignored as the webpage is an object of type gridbox and not of type Plot. (This is checked in the bokeh/io/export.py in the method def get_layout_html())
The output is a png of a width of 800px which is kind of useless as the actual information is crushed (while the legends are nicely scaled):
Any ideas how to set the width of my PNG export to useful values?
Is there a way to convert a gridboxto a Plot?
Thanx!
You should've received a warning saying that the width argument will be ignored since you're passing into export_png something that's not a plot.
A way of achieving what you want:
webpage = gridplot(..., sizing_mode='stretch_width')
webpage.width = 1800
export_png(webpage)

Error: plot.new has not been called yet

The following code produces an image. No problem.
change <- function(score, d, k, p) {k*(score - 1/(1+k^(d/p)))}
parameters <- c(10:110)
colorshelf <-rainbow(length(parameters), start=1/6) #yellow is low
for(i in seq_along(parameters)) {
curve(change(score=1, d=x, k=parameters[i], p=-800), from=-500, to=500, add=T, ylim=c(0, 100), col=colorshelf[i], xlab="rating difference", ylab="gain for winning")
}
legend.index <- round(quantile(seq_along(parameters)))
legend.param <- legend.index + min(parameters)
legend.color <- colorshelf[legend.index]
legend("right", title="k-factor", lty=c(1,1), legend=legend.param, col=legend.color)
Now I would like to save the image to a file with specified resolution. So I add:
png(filename="gain by ratingdiff.png", res=30, width = 1000, height = 1000)
and
dev.off()
before and after the code block. But then I get two errors, complaining about plot.new has not been called yet.
I know this issue came up like a million times. And there are so many posts about this here on stackoverflow. But none of these really helped me out. I tried adding plot.new() at different places in the code. But that did not help.
The help page on plot.new() reads:
"This function (frame is an alias for plot.new) causes the completion of plotting in the current plot (if there is one) and an advance to a new graphics frame. This is used in all high-level plotting functions and also useful for skipping plots when a multi-figure region is in use. "
But is this really what I want? I mean, I want to draw everything in one graphics device, so why would I want to cause the completion of plotting, except maybe at the end of the code.
Others have suggested, the problem is related to the usage of RStudio, but I do not use RStudio. I use Notepad++ in combination with NppToR.
Also, someone suggested to add { } around the code block (did not work).
Please help.
Before using curve()function is needed to run plot(). That is why you have a problem when saving the plot.
Before running:
for(i in seq_along(parameters)) {
curve(change(score=1, d=x, k=parameters[i], p=-800), from=-500, to=500, add=T, ylim=c(0, 100), col=colorshelf[i], xlab="rating difference", ylab="gain for winning")}
you need to run plot() giving the margins, labels and information useful to represent your images.

convert textGrob to imageGrob/rasterGrob?

Apologies if this is very straightforward. Actually I hope it will be!
I am trying to dynamically create images from text which I can then resize and plot (either stretched or squashed) to produce a motif-type graph.
I started out using images (which I'd generated using png() and ggplot()) and plotting them as annotation_custom()
require(ggplot2)
require(grid)
require(gridExtra)
qplot(c(0,10),c(0,10)) +
annotation_custom(rasterGrob(image=readPNG("1999.png"),x=0,y=0,height=1,width=1,just=c("left","bottom")),
xmin=0,xmax=5,ymin=0,ymax=7.5)
to produce:
This is fine, but it's awkward to create the images dynamically if they are not the same size, using png(), plus it's clunky to persist them to file, so I tried to see if I could use a textGrob:
myText<-"1000"
myTextGrob<-textGrob(myText,just=c("left","bottom"),gp=gpar(fontsize="100",col="red",fontfamily="Showcard Gothic"))
qplot(c(0,10),c(0,10))+annotation_custom(myTextGrob,0,0,0,0)
and got this, which is fine, except....
...it doesn't seem possible to stretch & skew it in the same way as a rasterGrob so my question is - is it possible to create the textGrob and coerce it to a rasterGrob? Or is there another solution which will let me skew/stretch the textGrob?
Thanks in advance!
It doesn't seem easy without creating temporary files. Instead of raster files, you might use vector paths with the grImport package. There are two options to import text,
as a path; it works (example below), but there's no obvious way to bypass the ps to xml conversion step with intermediate files
as a text string; the xml is much shorter in this case, and could be created directly from R, but unfortunately I couldn't find a way to transform the two axes independently.
library(grImport)
scale_text <- function(text="hello world", scale=4, tmp=tempfile()){
tmp.ps <- paste0(tmp, ".ps")
tmp.xml <- paste0(tmp, ".xml")
string.ps <- paste0('%!PS
/Courier % name the desired font
20 selectfont % choose the size in points and establish
% the font as the current one
1 ', scale, ' scale % scale axis
72 500 moveto % position the current point at
% coordinates 72, 500 (the origin is at the
% lower-left corner of the page)
(', text, ') show % stroke the text in parentheses
showpage % print all on the page
')
cat(string.ps, file=tmp.ps)
PostScriptTrace(tmp.ps, tmp.xml)
readPicture(tmp.xml)
}
hello <- scale_text()
grid.newpage()
grid.picture(hello)

removing x axis in error.bars

I've been having a problem today, I want to remove the x-axis from the following R-plot, but it just won't disappear. I want the axis to be on top.
Is anybody able to help me?
library(psych)
temp <- describe(attitude)
error.bars(stats=temp,xaxt="n")
axis(3)
You can use fixInNamespace() to edit the error.bars() function in the psych NAMESPACE. Try:
fixInNamespace(error.bars)
That will open the function in a rudimentary text editing window. Find the axis() calls and comment out the ones you don't want. Exit the editor and R will update the function in the NAMESPACE.
Then try using the function again.
Alternatively, you can print the code for error.bars() to the prompt, copy it into a text editor, change the name of the function, say to my.error.bars, and comment out the axis() calls as before. Save the function in a file and source() it into your session or copy and paste the function in. Then use to your heart's desire.
A third alternative, is to work out how error.bars() does it's base plotting - look at the code. Recreate that plot yourself, without axes, then call error.bars() with add = TRUE.
As in the comment, you can edit the source code. Easiest way is probably to use 'fix':
eb = fix(error.bars)
should pop up an editor. Change the axis(1,.etc.) calls to axis(3,.etc.). Then you have a new function called eb() that works like error.bars.
You might want to tweak some other things too, like the title which stomps on the axes when placed at the top.
Just to show what Gavin means with add=T :
group <- factor(rep(1:10,10))
y <- (1:10)[group] + rnorm(100)
grmean <- tapply(y,group,mean)
plot(1:10,grmean,xaxt="n",type="n")
unstacked <- unstack(data.frame(y,group),y~group)
error.bars(unstacked,add=T)
axis(3)
gives :

Resources