It is easy to change the default strip height for lattice plots: the par.strip.text argument is all that one needs. But is there a simple way to to have strips of different heights within one multi-panel lattice plot?
I have in mind a plot with two rows of panels. The height of the strips in the first row would differ from the height of the strips in the second row.
I think that I can create such a figure by creating two plots –– one for the first row, another for the second row –– and then using grid.layout to position them. But I'd like to know if there is a more straightforward way to create such a figure.
I modified an example from this question (which is a much closer duplicate) and managed to achieve this:
bgColors <- c("black", "green4", "blue", "red", "purple", "yellow")
txtColors <- c("white", "yellow", "white", "white", "green", "red")
stripHt <- rep(c(-1,0),each = 3)
# Create a function to be passes to "strip=" argument of xyplot
myStripStyle <- function(which.panel, factor.levels, ...) {
panel.rect(0, stripHt[which.panel], 1, 1,
col = bgColors[which.panel],
border = 1)
panel.text(x = 0.5, y = 0.5,
font=2,
lab = factor.levels[which.panel],
col = txtColors[which.panel])
}
xyplot(yield ~ year | site, data = barley, strip=myStripStyle)
Ignore the horrible colors. You get the point, we're just using a custom strip function.
Related
I am sure versions of this question has been answered before but I am looking for a specific problem I am working on.
I have a list of values for example:
[81,43,31,20,10,5,1,0]
I want to assign colors between white and black, higher the value the darker it gets fashion, to each one of these values.
So far in R I can use the colorramppalette function and the image function assigns these colors to the values in my heatmap automatically.
I want to learn how to assign these colors manually to get more control over the coloring aspect of my data.
vec = c(81,43,31,20,10,5,1,0)
myColors = c("red", "blue")
myRangeFunction = colorRampPalette(myColors)
myColorRange = myRangeFunction(max(vec))
myColors = myColorRange[vec]
plot(x = seq_along(vec),
y = vec,
cex = 2,
pch = 19,
col = myColors)
Looking at this code:
pairs(Iris[1:3], main = "Anderson's Iris Data -- 3 species",
pch = c(21), cex = 2,bg = c("red","green3","blue")[unclass(iris$Species)])
is it possible to show the groups/classes Species as legend color coded?
pairs(iris[1:3], main = "Anderson's Iris Data -- 3 species",
pch = c(21), cex = 2, bg = c("red","green3","blue")[unclass(iris$Species)], oma=c(4,4,6,10))
par(xpd=TRUE)
legend(0.55, 1, as.vector(unique(iris$Species)), fill=c("red", "green3", "blue"))
From ?pairs:
Graphical parameters can be given as arguments to plot such as main. par("oma") will be set appropriately unless specified. Hence any attempts to specify par before pairs will result in override.
Additionally it is very complicated to control the legend position in pairs.
I recommend using library(GGally)
library(GGally)
ggpairs(iris, aes(color = Species), columns = 1:4)
I can create a dendrogram using
x<-1:100
dim(x)<-c(10,10)
set.seed(1)
groups<-c("red","red", "red", "red", "blue", "blue", "blue","blue", "red", "blue")
x.clust<-as.dendrogram(hclust(dist(x)))
x.clust.dend <- x.clust
labels_colors(x.clust.dend) <- groups
x.clust.dend <- assign_values_to_leaves_edgePar(x.clust.dend, value = groups, edgePar = "col") # add the colors.
x.clust.dend <- assign_values_to_leaves_edgePar(x.clust.dend, value = 3, edgePar = "lwd") # make the lines thick
plot(x.clust.dend)
However I want to delete the scale of height information in the left as shown in Figure below.
My guess is that it should be extremely trivial but I am not able to find a way to do this. One solution which I don't want is using the ggplot2 as below:
ggplot(as.ggdend(dend2))
This is because I will loose some of the formatting like color_bars()
The graphical parameter 'axes = FALSE" can be used to remove the distance measure for the plot.dendogram command:
plot(x.clust.dend, axes=F)
This will produce the following dendogram without distance axis:
You can just set yaxt = "n"
plot(x.clust.dend, yaxt = "n")
You can add another axis with
axis(side = 2, labels = FALSE)
I have a dot plot and I'd like to color the dots so I have a d$color vector that corresponds to the color for a particular dot.
Question 1:
When you run the code below you can see the dots are not colored properly? Do you know how to color them properly? The code needs to dynamically handle the situation where the colors change. For example in this case "red" is the first color but that will not always be the case.
Question 2: Do you also know how to make the dots filled instead of transparent?
library(mosaic)
binwidth <- 1
dat <- c(1, 1, 1, 2, 3, 3, 4, 4, 5, 5)
d <- data.frame(x=dat, color=c("red", "green", "blue", "blue", "purple", "red",
"red", "blue", "green", "green"))
dotPlot(~x, data=d, groups=color,
breaks=seq(min(d$x) - binwidth, max(d$x) + binwidth, binwidth),
cex=1, col=as.factor(d$color))
Question 3: Can you run this code? The soltuion does not seem to work here:
n=50
r =rnorm(n)
dat = sample(r ,n= 1,size = n, replace = TRUE)
d = data.frame( x = dat, color = c(rep("red",n/2), rep("green",n/2)))
dotPlot(d$x, breaks = seq(min(d$x)-.1,max(d$x)+.1,.1)) # this works
dotPlot(d$x, breaks = seq(min(d$x)-.1,max(d$x)+.1,.1), groups = color,col = levels(d$color) ) # this does not work
To colour the points as desired, pass a vector of colours that corresponds to the colours that you want for your groups (so here, a vector of 4 colours, not a vector of 10 colours).
dotPlot(~x, data=d, groups=color, col=levels(d$color),
breaks=seq(min(d$x) - binwidth, max(d$x) + binwidth, binwidth))
To change the symbol, use pch (see ?pch for a list of built-in plotting characters).
dotPlot(~x, data=d, groups=color, col=levels(d$color), pch=20,
breaks=seq(min(d$x) - binwidth, max(d$x) + binwidth, binwidth))
Regarding the Q2, simply changing the type of "point" by default with the argument "pch".
dotPlot(~x, data=d, groups = color, breaks = seq(min(d$x)-binwidth, max(d$x)+binwidth,binwidth), cex = 1, col = d$color, pch = 16)
At first I thought this would be trivial, but I could not figure out how to combine rectangles with lines in the legend of a lattice plot. Consider the following example:
library(latticeExtra)
xyplot(rnorm(10) ~ 1:10,
key=list(rectangles=list(size=2, border=F),
text=list(c("Zero", "One", "Two"), col="black"),
col=c("black", "lightgrey", "darkgrey"), divide=1, columns=1,
x=0.01, y=0.95, corner=c(0,1) ),
panel=function(x,...){
panel.abline(v=3, lty="dashed")
panel.xblocks(x,x>5, col="lightgrey")
panel.xblocks(x,x>7, col="darkgrey")
panel.xyplot(x, ...) } )
Instead of 3 rectangles, I would like to have 2 rectangles filled with the appropriate colours, and one dashed line above or below these two rectangles. If I provide a lines argument, then both lines and rectangles will be drawn for all elements (i.e. there will be 2 rectangles and 2 lines simultaneously next to each other).
How can I set up the legend key so that I get this mix of "symbols"? That is, how can I get one dashed line and two rectangles with the appropriate text and colours?
Any help is greatly appreciated! My apologies if this is trival. Please help me see the obvious! :)
This is a rather late answer but it is something I still do. One approach is to use auto.key in the function and then modify the lattice object with update(obj, key = newKey). A more general approach, as suggested by #josh-obrien, is to use the grid functions that under lattice. However, this typically requires empirical tweaking of the coordinates as can be seen in the need to use 3 decimal places of precision to place the dashed lines.
# relative position may be sensitive to absolute sizes
library(latticeExtra)
dev.new(width = 5, height = 5)
set.seed(1234)
# same code as in question, re-written a little bit
# using "transparent" for the 1st of the three rectangles
# using a grid call in the panel function to place the dashed line
xyplot(rnorm(10) ~ 1:10,
key = list(rectangles = list(size = 2, border = FALSE,
col = c("transparent", "lightgrey", "darkgrey")),
text = list(c("Zero", "One", "Two"), col = "black"),
columns = 1, corner = c(0.01, 0.95)),
panel = function(x,...) {
panel.abline(v = 3, lty = "dashed")
panel.xblocks(x, x > 5, col = "lightgrey")
panel.xblocks(x, x > 7, col = "darkgrey")
panel.xyplot(x, ...)
grid::grid.lines(c(0.04, 0.07), c(0.935, 0.935),
gp = gpar(lty = "dashed", col = "black"))
}
)
[![plot with combined elements in legend][1]][1]
[1]: https://i.stack.imgur.com/K7AJN.png