My question is similar to this:
Plotting bar plot below xyplot with same x-axis?, but for the lattice package rather than ggplot.
I have 21 xyplots, all with the same x-axis scale, but different y-axis scales. I would like to plot all 21 lines with only 1 x-axis, but 21 different y-axes scales (one row per line). I nearly have it here:, but the redundant x-axes printed to each panel make this figure ridiculous. My script:
xyplot(numhr~year | spp, xlab = "Time(years)",
ylab = "Abundance (# per party hr)", type = "l", aspect = "fill",
strip = FALSE, scales = list(relation = "free"), as.table = TRUE,
layout = c(1,21), xlim = c(1940,2010))
Any help?
~Kevin
As per the comment above, the necessary change to my code to make this work involves adding 'y = list(relation = "free")' to the 'scales' component. Edited code below:
xyplot(numhr~year | spp, xlab = "Time(years)",
ylab = "Abundance (# per party hr)", type = "l", aspect = "fill",
strip = FALSE, scales = list(y = list(relation = "free")), as.table = TRUE,
layout = c(1,21), xlim = c(1940,2010))
Which produces this (unfortunately the y-axes are still too condensed, but this does address the question originally posed):
Related
I want to only have labels every second number, but have the small ticks for every number in my graph. As you can see in the figure I added, the labels are every 2nd tick on the X-axis.
But I want to achieve the result that's on the Y-axis:
With ggplot, this is possible with ggh4x and if_elfse. But I can't find a way how to do this in ggsurvplot. This is my code, for the first picture. The code for the second picture is found here: Code 2
ggsurvplot(fit, data = d,
conf.int = F,
censor = F,
palette = c("green", "purple", "red"),
legend.labs = c("Reference water (pH 7.3)\n(N = 66)",
"Acidic al-poor (pH 5.8)\n(N = 66)",
"Acidic al-rich (pH 5.8)\n(N = 66)"),
legend.title = "Water quality",
xlab = "Days",
xlim = c(1,23),
break.time.by = 2
)
Thank you in advance for yor help.
As ggsurvplot returns a list containing the plot as a ggplot2 object you could achieve your desired result using ggh2x by overriding the x scale as in the example code by #tjebo from Adding minor tick marks to the x axis in ggplot2 (with no labels).
Making use of the default example from ?ggsruvplot:
library(survminer)
library(survival)
library(ggh4x)
fit<- survfit(Surv(time, status) ~ sex, data = lung)
p <- ggsurvplot(fit, data = lung, main = "Survival curve",
xlab = "Days",
xlim = c(1,23))
p$plot +
scale_x_continuous(minor_breaks = seq(0, 24, 1), breaks = seq(0, 24, 2), guide = "axis_minor") +
theme(ggh4x.axis.ticks.length.minor = rel(1))
#> Scale for 'x' is already present. Adding another scale for 'x', which will
#> replace the existing scale.
My problem is with the legend. The legend is cut off, so it is missing two values. How do I go about moving legends to the title position, while still maintaining correct formating so that everything fits and is aligned to the plot?
My legends are of varying lengths so it would be great to have a way to always have them perfectly line up above the plot.
x<-c(1, 30,60)
y<-c(.001,.023,.03)
data<-cbind(x,y)
N<-100
plot_pdf_1<-function(data, ymax, big){
par(cex=big)
plot(data, type = "l", lwd=2,xaxt="n", yaxt="n", xaxs="i", yaxs="i", ylim=c(0,ymax))
my_at<- c(0,10,20,30,40,50,60,70,80,90) # to specify the tick marks
#initialize all points to zero first
#number of data points
N_o1_male<-0
N_o1_female<-0
N_o139_male<-0
N_o139_female<-0
N_non_male<-0
N_non_female<-0
#subscript format to be used in my legend
my.expressions <-c(as.expression(bquote('N'['1M']*' = '*.( N_o1_male))), as.expression(bquote('N'['1F']*' = '*.( N_o1_female))), as.expression(bquote('N'['2M']*' = '*.( N_o139_male))),as.expression(bquote('N'['2F']*' = '*.( N_o139_female))), as.expression(bquote('N'['3M']*' = '*.( N_non_male))),
as.expression(bquote('N'['3F']*' = '*.( N_non_female))))
par(xpd=TRUE)#to allow legend in outer margins
legend("topleft",legend=my.expressions,inset=c(0,-.11),
text.col="black",box.col=0, bty="n", cex = .75, lty= c( 1,2,1,2,1,2), col = c("purple","purple","blue","blue","black","black"),horiz = TRUE,seg.len = 1)
}
#formatting to plot in a two by two layout
op <- par(mfrow = c(2,2),
oma = c(5,4,0,0) + 0.1,
mar = c(0,0,1,.5) + 0.1)
#calls each plotting function and layout in a two by two
twobytwo<-function(data,ymax,big){
op
plot_pdf_1(data,ymax,big)
plot_pdf_1(data,ymax,big)
plot_pdf_1(data,ymax,big)
plot_pdf_1(data,ymax,big)
title(xlab = "Age (years)",
ylab = "Probability Density",
outer = TRUE, line = 3)}
twobytwo(data, ymax=.04, big=1) #calls the two by two function which lays out four plots in a two by two format. The plots share the same axis.
Three solutions:
Reduce font with cex
Remove the spaces on both sides of the ' = '
Widen your chart. You can set the chart size with win.graph() in
Windows or X11() or quartz() in other OS.
Using win.graph(width=11, h=7) before the op<-... call
I want to be able to show three different density curves on the same axis. I've got the code below so far but i don't know how to combine them to so that they can
curve(dnorm(x,mean=0,sd=1),col="darkgreen",xlim=c(-4,8),ylim=c(0,.8))
curve(dnorm(x,mean = 0,sd=1.5),col="red",xlim = c(-5,8),ylim=c(0,.6))
curve(dnorm(x,mean = 0.5,sd=0.5),col="black",xlim = c(-2,8), ylim =c(0,1))
This is the basic solution. You can add more formatting if need be (for axes etc). Note you need to change the xlim and ylim to match on the plots.
curve(dnorm(x,mean=0,sd=1),col="darkgreen",xlim=c(-5,8),ylim=c(0,1), ylab = "")
par(new = TRUE)
curve(dnorm(x,mean = 0,sd=1.5),col="red",xlim = c(-5,8),ylim=c(0,1), ylab = "")
par(new = TRUE)
curve(dnorm(x,mean = 0.5,sd=0.5),col="black",xlim = c(-5,8), ylim =c(0,1), ylab = "")
I´m starting with lattice. I have several plots and I want to dispose then with grid.arrange
Here´s an example for two graphs
graph1<-useOuterStrips(barchart(value1~Var1|Var2+Var3,data=table.df, ylab=NULL)
graph2<-useOuterStrips(barchart(value2~Var1|Var2+Var3,data=table.df, ylab=NULL)
grid.arrange(graph1,graph2, nrow=2, ncol=2, left=("percentage"))
It works well, however I would like to change the heighs of each rown on the grid (to expand the graphs). I have tried to inlcude the argument heighs on grid.arrange but doesn´t seens to do the job.
Any suggestion?
The correct argument to pass to grid.arrange and be passed to grid.layout is heights.
That being said, if you send it identical heights for all cells in the layout, the heights will stay the same. You may need to increase the size of your plotting device.
If you want different heights for each row you can.
Using the example from ?barchart
x <-barchart(yield ~ variety | site, data = barley,
groups = year, layout = c(1,6), stack = TRUE,
auto.key = list(space = "right"),
ylab = "Barley Yield (bushels/acre)",
scales = list(x = list(rot = 45)))
y <-barchart(yield ~ variety | site, data = barley,
groups = year, layout = c(1,6), stack = TRUE,
auto.key = list(space = "right"),
ylab = "Barley Yield (bushels/acre)",
scales = list(x = list(rot = 45)))
grid.arrange(x,y,ncol=1, heights = c(1.5,2))
Which is ugly and useless, but shows the concept.
In the default Lattice barchart, categorical variable labels are placed on the left. I want to put them on the right as well. I can manipulate locations of numeric ticks and labels using scales, but have had no success in moving the categorical labels. Study of help(barchart) and Sarkar's book has not led to the answer (which is not to say the answer isn't there).
You were on the right track with the scales argument. Try adding alternating = 3 to the list of y scale parameters.
barchart(variety ~ yield, data = barley, groups = year, stack = TRUE,
ylab = "Barley Yield (bushels/acre)",
scales = list(x = list(rot = 45), y = list(alternating = 3)),
horizontal = TRUE)