I am using lattice package from R. The produced plot has legends, and I want to change the text position of these legends rather than the default (which is always left) to the right position. Example:
As you can see, "Before" the legends produced by lattice like this, whcih I would like to make them like "After".
My trying code:
print(barchart(Value~Topic|Project, d2, groups=Variable, origin=0,
main="Title", auto.key=list(corner = c(0.99, 0.99),points=TRUE,
rectangles=FALSE, background = "gray97" ,
title="Legends", cex=0.8, cex.title=1), xlab="topics",
ylab=expression(paste("Cose(", theta, ")"))) )
You can use key to construct your legend in the order you want. Here is an example drawing the points column before the text column:
library(lattice)
data(Cars93,package="MASS")
labels=levels(Cars93$Cylinders)
xyplot(Price~EngineSize,groups=Cylinders,data=Cars93,
key=list(space="right",adj=0,title="Legends",
points=list(pch=1,
col=trellis.par.get("superpose.symbol")$col[1:length(labels)]),
text=list(labels))
)
Related
Is it possible to put a text box so many cm/inches above a line in graph in R? (Whithout changing scale of graph). So im plotting the image using plot and i want to specify that the text using the function: text() but I always want the text to be 1cm above the arrow at the specified x-coordinate.
enter image description here
You can do this simply with ?text. So not entirely with cm's but if you know the range of your data you can position your text as data points in the plot.
Example:
Let's make some test data.
dat <- matrix(rnorm(3*4), ncol=2)
colnames(dat) <- c("v1", "v2")
Create a scatter plot. You can of course apply text to any graphical plot, but I'm keeping it simple.
plot(v2 ~ v1, data = dat)
And now just create a line, in whatever direction. I'll just go with an abline at height 1.0 on the y-axis
abline(h=1.0)
text(1,1,"this is an abline", pos = 1)
With text I add text on position 1,1 (x, y) in the plot. I adjust it with pos so It doesn't get crossed by the abline.
Good luck!
Here's a fiddle for a simplified version of a plot I am trying to generate.
On line 44 the plot points are sized according to 1/Error:
main_aes = aes(x = Date, y = Popular_Support, size=1/Error)
But instead of displaying 1/Error values in the legend, I want it to display Sample Size which is 1/Error^2, which the legend title being Sample Size.
I only want this displayed in the legend, but I still want the original values to weight the point sizes.
How can I do this? How can I perform a calculation on the legend text that is displayed and change the legend title?
You can do this as follows:
plot + scale_size_continuous(breaks=seq(40,70,10), labels=seq(40,70,10)^2,
name="Sample Size")
Also, plot is an R function, so it's probably better to use a different name for your plot objects.
I am producing heatmaps with heatmap.2. I know how to controls many of the parameters but still I have not found a way of making the key of color only wider or putting it as a strip in a side or bottom of the plot.
With keysize it modifies both height and width proportionally.
Also when using ColSideColors I am using legend() to put the color labels, but 'topright' is not at the top-right. I know that this is something about the plot area, margins etc, but I have not found yet a good explanatory text of how heatmap.2 plot is structured and how to positioned things by coordinates and how to deal with oma, mar etc. Depending on the margins, samples, tree depth, etc. the legend could be placed in an open area or overlaps a bit of the heatmap. Any point to good texts for understanding theses issues with R graphics would be truly appreciated.
The coded used is:
df<- data.frame( x1=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x2=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x3=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x4=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x5=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x6=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x7=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,x8=rnorm(120,mean=rep(1:3,each=4),sd=0.2)
,y1=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y2=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y3=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y4=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y5=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y6=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y7=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
,y8=rnorm(120,mean=rep(c(1,2,1),each=4),sd=0.2)
)
dataMatrix <- as.matrix(df)[sample(1:120),]
heatmap.2(dataMatrix
, col=rev(brewer.pal(11,"RdBu"))
, density.info="none"
, key=TRUE
, symkey=FALSE
, trace="none"
, cexRow=1
, scale='row'
, margins =c(10,9)
, ColSideColors=c(rep("red", ncol(df)/2), rep("green", ncol(df)/2))
, main="Log2_intensities median centered"
, keysize=0.9)
legend('topright', c("x", "y"),lty=1, col=c("red", "green"), cex=0.8)
There is the way to organise your plot described here: Moving color key in R heatmap.2 (function of gplots package)
When having a ColSideColors, heatmap.2 will draw the plot as
1 ColSideColors
2 heat map
3 ... so on as in the link above
Never tested with the RowSideColors. In the other words you can organise the plot using lmat, lwid, lhei parameters of heatmap.2. this could give you some space for your legend.
You could try adding the 'inset' parameter and playing with the sizes to move the legend further right (first value) and/or further towards the top (second value) e.g:
legend('topright', inset = c(.02,.02), etc...)
I have a lattice bar chart with multiple panels and I would like to add the sum of each bar on top of the bars (e.g. (70) on top the of first bar on the top left, (20) on the second one, (150) on the third one etc.).
There is a similar question here but I could not find a way to adapt that code for my plot. Unlike in that example, what I would like to do is to add the 'total sum' of men and women on top of each bar vertical bar. I also could not label them separately using ltext as shown here. Any suggestion, using ltext or any other way, would be very helpful.
civ1<-c("Single","Single","Marr","Marr","Single","Single","Marr","Marr","Single","Single","Marr","Marr","Single","Single","Marr","Marr")
Sex<-rep(c("women","men"),8)
Year<-rep(c(rep(1990,4),rep(2000,4)),2)
Type1<-c(rep("Traditional",8),rep("Dual-earner",8))
Earn1<-c(seq(10, 160, by = 10))
df<-as.data.frame(cbind(civ1,Sex,Year,Type1,Earn1))
df$Earn1<-as.numeric(levels(df$Earn1))[df$Earn1]
my.key<-list(space="bottom",text=list(c("Women","Men"),col=c("black","black")), columns=2,points=T,pch=15,col=c("darkgray","lightgray"),cex=0.8)
labels=c("70","20","150","110")
print(figure1<-barchart(Earn1~civ1|Year+Type1,df,groups=Sex, ylim=c(0,350),horizontal=F,col=c("darkgray","lightgray"),cex=0.8,ylab="Earnings",stack=T,layout=c(2,2),key=my.key,
par.settings = list(strip.background=list(col=c("white","lightyellow")),
panel=function(x,y,subscripts...){
panel.grid(h=-1,v=0)
panel.barchart(...)
ltext(1,200, labels[subscripts]) #not working!
})))
I see several problems. First, your panel= parameter is inside your par.settings parameter which is incorrect. It should be passed to barchart directly. Then you have some syntax problems with a missing comma and I'm not sure how your labels were intended to work with only 4 values. Anyway, the following code should work.
barchart(
Earn1~civ1|Year+Type1,df,
groups=Sex,
ylim=c(0,350), cex=0.8, ylab="Earnings",
horizontal=F, stack=T, layout=c(2,2),
col=c("darkgray","lightgray"),
key=my.key,
par.settings = list(strip.background=list(col=c("white","lightyellow"))),
panel=function(x,y,subscripts,...){
panel.grid(h=-1,v=0)
panel.barchart(x,y,subscripts=subscripts,...)
t <- aggregate(y~x, data.frame(x,y), FUN=sum)
panel.text(t$x,t$y, labels=t$y, pos=3)
}
)
Aside from fixing the problems described above, I've use aggregate() to calculate the total for each column and used those values to plot the text labels at the appropriate spot. The resulting plot is below
I have to draw a 20 plots and horizontally place a legends in each plots.
I gave the following command for the first plot:
plot(x=1:4,y=1:4)
legend("bottom",legend = c("a","b","c","d"),horiz=TRUE,text.font=2,cex=0.64)
then for the second plot I tried :
plot(x=1:2,y=1:2)
legend("bottom",legend = c("a","b"),horiz=TRUE,text.font=2,cex=0.64)
But because the size of the character vector passed to legend argument are different I get the size of the legend different.
Since I have to plot so many different plots having varying sizes of legends,I would want to do it in an automated fashion.
Is there a way to do this which can fix the size of the legend in all the plots and fit it to graph size?
par(cex=.64) at the beginning should suffice
op <- par(cex=.64) # this fix the legend size for all plots
plot(x=1:4,y=1:4)
legend("bottom",legend = c("a","b","c","d"),horiz=TRUE,text.font=2) # no need to set cex anymore
plot(x=1:2,y=1:2)
legend("bottom",legend = c("a","b"),horiz=TRUE,text.font=2)
par(op) # At end of plotting, reset to previous settings