Axis titles on vioplot - r

I want to make a violin plot which is working fine. I have created the plot and added a title using the functions:
library(vioplot)
vioplot(x1, x2, x3, names=c("red", "green", "blue"), col="aliceblue") col="aliceblue")
title("Violin Plot")
But can't get the y or x axis titles which are the last things I need. I have tried.
ylab=("response")
ylab("response")
ylabel=("response")
ylabel("response")
All separately but it is not working. Do I have to include the y axis title in the main code for the plot?
Likewise I cannot label the X-axis ("colours").
Is this something which is beyond vioplot? and is there a way round it that is relatively basic?
Thanks

Ifvioplot (from an unnamed package) is a base or lattice graphics function, then you should set ylab="" in the call, and you can then use title(ylab="response", xlab="colours") to fill in with "response"/"colours" or whatever character values you desire. The title function is used (after a plot-like call) for several named locations on the abstract base plot layout: "main" for what most people would call "title", and/or "xlab" and "ylab" for the centered axis-descriptions (but not the tick labels) .
?title

Related

add multiple legends to a heatmap in R

My question is that I want to add the categorical variables' legends onto the graph but somehow when I used "topright", it did not work for me (see the image below). Basically my idea is to fill the blank area with the legends for my categorical variables on the side of the heatmap. My codes look like
heatmap.3(performance, Colv =NA,RowSideColors=row_annotation,col=my_palette)
par(lend = 1) # square line ends for the color legend
legend("topright", # location of the legend on the heatmap plot
legend = c("category1", "category2", "category3"), # category labels
col = c("gray", "blue", "black"), # color key
lty= 1, # line style
lwd = 10 # line width
)
Also I want to put multiple legend onto the plot but don't know how to specify their positions using x and y as there are no coordinates in my plot.
Thank you so much!
A simple fix to your problem would be to use the option inset=# (where # is some floating point number with a comma after it) following your "topright" specification after its respective comma, which would indicate how to place your legend relative to your graph.
Instead of specifying the default position "topright", perhaps you may want to try restructuring your code in a more personally customized manner, namely utilizing an x-y axis approach, such as for instance use :
dev.new(xpos=#,ypos=#)
Or you may also consider using:
legend.position=c(#,#)
Try these options, even though you say you have no access to coordinates, which is rare for graphical utilities in R, but may well be a future edit to heatmap.3. You could also use a fancy R utility called locator(1) to point and click with your mouse where you want to see your legend.
In general, the legend option is formally defined as:
legend(location, title, legend, ...)
If you have any more questions about the legend utility in R, please type in help(legend) in your R command line (in R Studio, for instance, if you use that).
To address your question on multiple legends, please consult: Plotting multiple legends

R lattice barchart: How to write the total sum on each bar in multiple panels?

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

Increasing the size of axis labels in a Wireframe Plot

I want to adjust the size of the text in the axis labels of the wireframe method in R (found in the lattice package).
It seems like it should just be a matter of specifying
cex.lab=2
as is the case with most other plots. However, this does not increase the font size.
For example:
some_data <- expand.grid(c(1:10), c(1:10))
some_data$z <- sin(some_data$Var1 + some_data$Var2)
wireframe(z~Var1*Var2, some_data, scales=list(arrows=FALSE, cex=1.5), xlab='blah1', ylab='blah2', zlab='blah3')
wireframe(z~Var1*Var2, some_data, scales=list(arrows=FALSE, cex=1.5), xlab='blah1', ylab='blah2', zlab='blah3', cex.lab=4)
should produce a second plot with axis labels 4 times larger than the ones in the first. Instead they are identical.
Two ways, there might be others:
wireframe(z~Var1*Var2, some_data,
trellis.par.set(list(axis.text=list(cex=2))),
scales=list(arrows=FALSE),
xlab='blah1', ylab='blah2', zlab='blah3')
The canonical reference for this is Sarkar's "Lattice" text and this is described in the Parameter System chapter on pages 126-128.
It also appears that you can use nested arguments within scales. Drop the par.settings call and use this instead:
..., scales=list(arrows=FALSE, axis=list(text=list(cex=2))), ...

plot multiple line segments on one graph using R

How can I duplicate this style of graph, with multiple plots on one graph, and, preferably, legends attached as below.
I have tried the concept of "facet" but ggplot2 and trellis:xyplot both think of facets as separate panels rather than overlaid plots.
I can do it using plain Jane plot() and line().. but was using ggplot2 and woudl like to get multiple lines on one plot in that package.
Here is some example data in long form (captured from the plot using a nifty app called "Graphclick")
comp <- read.table(pipe("pbpaste"), header=T, sep=',')
company, year, sales
Apple,1975.003,17298.457
Apple,1977.302,16784.502
Apple,1978.314,17298.457
Apple,1980.246,20730.098
Apple,1981.533,27608.426
Apple,1984.293,40862.852
Apple,1986.408,50468.617
Apple,1987.328,48236.188
Apple,1988.892,35676.547
Apple,1989.904,34616.582
Apple,1991.192,44732.742
Apple,1992.387,44732.742
Apple,1993.399,39055.324
Apple,1995.791,37894.922
Apple,1996.895,39648.746
Apple,1998.274,52804.367
Apple,1999.378,61399.512
Apple,2001.770,2.350e5
Apple,2005.265,7.735e5
Toshiba,1999.378,86856.6
Toshiba,2001.862,1.192e5
Toshiba,2004.069,1.495e5
Toshiba,2004.069,1.495e5
IBM,1975.003,22019.092
IBM,1975.830,27195.193
IBM,1976.934,30682.320
IBM,1978.130,31148.527
IBM,1980.430,35676.547
IBM,1981.625,35676.547
IBM,1983.005,39648.746
IBM,1985.305,40862.852
IBM,1986.408,46102.508
IBM,1987.512,64241.156
IBM,1989.996,75832.898
IBM,1991.100,84276.039
IBM,1992.295,85556.641
IBM,1993.307,79342.539
IBM,1994.779,79342.539
IBM,1995.791,84276.039
IBM,1996.895,95082.484
IBM,1996.895,95082.484
Commodore,1975.003,33588.051
Commodore,1975.830,34616.582
Commodore,1977.118,25219.982
Commodore,1978.130,23388.229
Commodore,1979.326,25992.234
Commodore,1980.521,21689.514
Commodore,1981.717,25219.982
Commodore,1984.201,6999.029
Commodore,1985.213,1670.460
Commodore,1986.408,1458.447
(source: asymco.com)
If you're looking for the most control, you could just use the low-level plot and lines commands. Use "plot" to generate the first graph (with title, xlimits, and ylimits), then use "lines" to add lines to that graph.
plot(0,type="n", xlim=c(0,10), ylim=c(0,10), xlab="X Label", ylab="Y Label", main="Title")
Then add lines using the lines command:
lines(1:10, 1:10, type="l", lty=2)
lines(2:4, 10:8, col=2, type="l")
lines(6:9, c(5,6,5,6), col=3, type="l")
You can fine-tune the look by using all of the parameters listed in the "par" help file ("?par")
so, in ggplot2, this code works
qplot(year, sales, data=comp, colour=as.factor(company), group= company, geom="path", log="y")
The only things left now is to format the value on the Y axis as numeric (not sci notation), and the labels are in an off-graph legend, rather than on the plots... Final suggestions welcomed.
This is a lot easier in the end than plot() + lines(), as that required support code to get the ranges, iterate over the group levels etc.

How can I add a legend to a goodness of fit plot in R?

I'm using goodfit from vcd package to produce goodness of fit plots.
I would like to add a legend stating the bars are the actual counts and the dots (connected by the line) are the fit using e.g. Poisson and ML.
legend does not work. How can I easily add a legend to this plot?
Thanks!
The plot function for goodfit objects is using the grid graphics system (see ?rootogram and getAnywhere(rootogram.default)).
You have two options:
use the rather limited grid.legend function (from package grid).
embed a base graphics legend in the grid plot using the gridBase package.
Here is a simple example for the first option:
library("vcd")
dummy <- rnbinom(200, size=1.5, prob=0.8)
gf <- goodfit(dummy, type="nbinomial", method="MinChisq")
plot(gf)
pushViewport(viewport(x=unit(0.8, "npc"),
y=unit(0.8, "npc"),
width=stringWidth("Legend x"),
height=unit(6, "line"),
name="vp1"))
grid.legend(labels=c("Legend 1", "Legend 2"), pch=1:2)
popViewport()
Modifying #rcs's answer to use grid_legend (in the vcd package along with goodfit), which is intended for users (grid.legend is an undocumented internal function), and to show a legend specifically geared to this plot. It would be nice to use fill=c(NA,"gray") as in legend in base graphics, but it's not implemented in grid_legend.
library("vcd")
dummy <- rnbinom(200, size=1.5, prob=0.8)
gf <- goodfit(dummy, type="nbinomial", method="MinChisq")
plot(gf)
grid_legend(x=unit(0.8, "npc"),
y=unit(0.8, "npc"),
labels=c("est NBinom (MinChiSq)","obs"),
title="",
pch=c(16,15),col=c("red","gray"))
It is hard to tell without a specific example (AFAIK it is not a limitation with goodfit), but I would check a few things with legend:
You can place a legend with "topright", "bottomleft", etc for the argument x.
You can query the x and y axis limits with par("usr"). If the plot is in log scale and you want to place the legend at the maximum value of y, you have to use 10^par("usr")[4], and so on.
Pass the argument xpd=NA to see if you are placing the legend outside of the plotting region and see if you need to set xjust or yjust.

Resources