Combine lattice xyplot and histogram - r

Could someone help me please to upgrade my plot?
a) In the plot, there should be print only one y-scale per row.
b) To print a more comfortable legend, that means
1) change the order of symbols and description,
2) print line in the same x-position like superpose.symbols,
3) and print symbols for the histogram.
d1 <- data.frame(x=c(NA, 13:20, NA), y = 25, z = c(rep('march', 5),
rep("april", 5)), color = c(c(rep(c("red", "green"), 2), "red"),
c(rep(c("blue", "yellow"), 2), "blue")), stringsAsFactors = FALSE)
d2 <- data.frame(x=c(NA, 20:27, NA), y = 23, z = c(rep('may', 5),
rep("june", 5)), color = c(c(rep(c("blue", "red"), 2), "red"),
c(rep(c("blue", "yellow"), 2), "blue")), stringsAsFactors = FALSE)
d1<-rbind(d1,d2)
sup.sym <- trellis.par.get("superpose.symbol")
sup.sym$alpha<-c(1, 0, 0, 0, 0, 0, 0)
sup.sym$col<-c(1,2,3,4,5,6,7)
sup.lin <- trellis.par.get("superpose.line")
sup.lin$col<-c(1,2,7,5,5,6,7)
sup.lin$alpha<-c(0, 1, 1, 1, 0, 0, 0)
settings<-list(superpose.symbol = sup.sym,superpose.line = sup.lin)
xyplot(y ~ x | factor(z), data = d1
,ylim = list( c(22, 26),c(22, 26), c(0, 1),c(0, 1) )
,layout=c(2,2)
,scales = list(y = list( relation = "free" ))
,par.settings = settings
,auto.key = list(text = c("A","B","C", "D")
,space = "right"
,lines = TRUE
)
,panel = function(x, y, subscripts) {
if(panel.number()>2){
panel.histogram(x,breaks=3)
}else{
panel.xyplot(x = x, y = y,
subscripts=subscripts,
col = d1[subscripts, "color"])
}
})

Related

change second y axis color in base R

Change secondary line axis color changes send color for ggplot, but I chose to go with base R, and would like to be able to select the second y axis color.
I have the following data:
df = structure(list(A = c("Q4-17", "Q1-18", "Q2-18", "Q3-18", "Q4-18",
"Q1-19", "Q2-19", "Q3-19", "Q4-19", "Q1-20", "Q2-20", "Q3-20",
"Q4-20", "Q1-21", "Q2-21", "Q3-21", "Q4-21", "Q1-22", "Q2-22",
"Q3-22"), B = c(69.45, 71.1, 74.94, 73.87, 93.61, 91.83,
95.38, 109.8, 133.75, 125.26, 118.22, 145.65, 144.9757185, 155.3464032,
184.367033, 179.8121721, 187.235487, 189.1684376, 184.3864519,
161.5300056), C = c(70.73, 71.73, 74.33, 73.27,
95.94, 94.38, 95.38, 109.8, 115.32, 116.92, 115.9, 113.87, 106.108147,
96.84273563, 111.5150869, 110.1228567, 110.7448835, 194.9684376,
187.7241152, 167.7665553), D = c(260.3, 216.02, 203.72,
203.52, 300.96, 320.77, 330.5, 413.52, 436.7, 474.96, 463.6,
501.87, 493.8865461, 497.1760767, 514.9903459, 503.7601267, 510.8362938,
614.9915546, 603.5761107, 593.660831), E = c(NA,
NA, NA, NA, NA, NA, NA, NA, 39.237, 35.621, 32.964, NA, 152.137,
140.743023, 167.809, 170.877, 117.517, 102.691723, 88.8, 76.2445528
)), class = "data.frame", row.names = c(NA, -20L))
df = df %>%
rowwise() %>%
mutate(sums = sum(D,E, na.rm = TRUE))
df = df[8:nrow(df),]
and this to generate my plot
x <- seq(1,nrow(df),1)
y1 <- df$B
y2 <- df$D
par(mar = c(5, 4, 4, 4) + 0.3)
plot(x, y1, col = "#000000",
type = "l",
main = "title",
ylim = c(0, max(df[,2:3])),
ylab = "Y1",
xlab = "",
xaxt = "n")
axis(1,
at = seq(from = 13, by = -4, length.out = 4),
labels = df$A[seq(from = 13, by = -4, length.out = 4)])
lines(x, df$C, lty = "dashed", col = "#adadad", lwd = 2)
par(new = TRUE)
plot(x, df$sums, col = "#ffa500",
axes = FALSE, xlab = "", ylab = "", type = "l")
axis(side = 4, at = pretty(range(y2)),
ylim = c(0,max(df[,3:5], na.rm = TRUE)),
col = "#00aa00") # Add colour selection of 2nd axis
par(new = TRUE)
plot(x, df$D , col = "#0000ff",
axes = FALSE, xlab = "", ylab = "", type = "l", lwd = 1)
mtext("y2", side = 4, line = 3)
but this does not colour my complete second y axis, nor labels, nor title
does any one have any suggestions to be able to set entire y2 axis to be #00AA00 - ticks, labels, and title?

Draw only positive octant with rgl.sphere in R

I would like to display only the positive octant of a unit sphere. So far, using the rgl package in R, I could show the entire sphere. Is it possible to "truncate" it? I am open to any other package that does the trick.
# Fake data
norm_vec <- function(x) sqrt(sum(x ^ 2))
data <- data.frame(T3 = runif(100), T6 = runif(100), P4 = runif(100))
norms <- apply(data, 1, norm_vec)
data <- data / norms
cluster <- sample(1:6, 100, replace = T)
#' Initialize a rgl device
#'
#' #param new.device a logical value. If TRUE, creates a new device
#' #param bg the background color of the device
#' #param width the width of the device
rgl_init <- function(new.device = FALSE, bg = "white", width = 640) {
if( new.device | rgl.cur() == 0 ) {
rgl.open()
par3d(windowRect = 50 + c( 0, 0, width, width ) )
rgl.bg(color = bg )
}
rgl.clear(type = c("shapes", "bboxdeco"))
rgl.viewpoint(theta = 30, phi = 0, zoom = 0.90)
}
#' Get colors for the different levels of a factor variable
#'
#' #param groups a factor variable containing the groups of observations
#' #param colors a vector containing the names of the default colors to be used
get_colors <- function(groups, group.col = palette()){
groups <- as.factor(groups)
ngrps <- length(levels(groups))
if(ngrps > length(group.col))
group.col <- rep(group.col, ngrps)
color <- group.col[as.numeric(groups)]
names(color) <- as.vector(groups)
return(color)
}
# Setting colors according to the cluster column
my_cols <- get_colors(cluster, c("#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7"))
# Ploting sphere
rgl_init()
par3d(cex = 1.35)
plot3d(x = data[, "T3"], y = data[, "P4"], z = data[, "T6"],
type = "s", r = .04,
col = my_cols,
xlab = 'T3', ylab = 'P4', zlab = 'T6')
rgl.spheres(0, 0, 0, radius = 0.995, col = 'lightgray', alpha = 0.6, back = 'lines')
arc3d(c(1, 0, 0), c(0, 1, 0), c(0, 0, 0), radius = 1, lwd = 7.5, col = "black")
arc3d(c(1, 0, 0), c(0, 0, 1), c(0, 0, 0), radius = 1, lwd = 7.5, col = "black")
arc3d(c(0, 0, 1), c(0, 1, 0), c(0, 0, 0), radius = 1, lwd = 7.5, col = "black")
bbox3d(col = c("black", "black"),
xat = c(0, 0.5, 1), yat = c(0, 0.5, 1), zat = c(0, 0.5, 1),
polygon_offset = 1)
aspect3d(1, 1, 1)
You can use cliplanes3d() to do that. You should also avoid using any of the rgl.* functions; use the *3d alternatives instead unless you really know what you're doing. It's almost never a good idea to mix the two types.
For example:
# Fake data
norm_vec <- function(x) sqrt(sum(x ^ 2))
data <- data.frame(T3 = runif(100), T6 = runif(100), P4 = runif(100))
norms <- apply(data, 1, norm_vec)
data <- data / norms
cluster <- sample(1:6, 100, replace = T)
#' Initialize a rgl device
#'
#' #param new.device a logical value. If TRUE, creates a new device
#' #param bg the background color of the device
#' #param width the width of the device
rgl_init <- function(new.device = FALSE, bg = "white", width = 640) {
if( new.device || rgl.cur() == 0 ) {
open3d(windowRect = 50 + c( 0, 0, width, width ) )
bg3d(color = bg )
}
clear3d(type = c("shapes", "bboxdeco"))
view3d(theta = 30, phi = 0, zoom = 0.90)
}
#' Get colors for the different levels of a factor variable
#'
#' #param groups a factor variable containing the groups of observations
#' #param colors a vector containing the names of the default colors to be used
get_colors <- function(groups, group.col = palette()){
groups <- as.factor(groups)
ngrps <- length(levels(groups))
if(ngrps > length(group.col))
group.col <- rep(group.col, ngrps)
color <- group.col[as.numeric(groups)]
names(color) <- as.vector(groups)
return(color)
}
# Setting colors according to the cluster column
my_cols <- get_colors(cluster, c("#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7"))
# Ploting sphere
rgl_init()
par3d(cex = 1.35)
plot3d(x = data[, "T3"], y = data[, "P4"], z = data[, "T6"],
type = "s", r = .04,
col = my_cols,
xlab = 'T3', ylab = 'P4', zlab = 'T6')
spheres3d(0, 0, 0, radius = 0.995, col = 'lightgray', alpha = 0.6, back = 'lines')
arc3d(c(1, 0, 0), c(0, 1, 0), c(0, 0, 0), radius = 1, lwd = 7.5, col = "black")
arc3d(c(1, 0, 0), c(0, 0, 1), c(0, 0, 0), radius = 1, lwd = 7.5, col = "black")
arc3d(c(0, 0, 1), c(0, 1, 0), c(0, 0, 0), radius = 1, lwd = 7.5, col = "black")
bbox3d(col = c("black", "black"),
xat = c(0, 0.5, 1), yat = c(0, 0.5, 1), zat = c(0, 0.5, 1),
polygon_offset = 1)
aspect3d(1, 1, 1)
clipplanes3d(c(1,0,0), c(0,1,0), c(0,0,1), d=0)
This produces

R: non-numeric arguments to binary operators

I am working with the R programming language. I am trying to make a "parallel coordinates plot" using some fake data:
library(MASS)
a = rnorm(100, 10, 10)
b = rnorm(100, 10, 5)
c = rnorm(100, 5, 10)
d = matrix(a, b, c)
parcoord(d[, c(3, 1, 2)], col = 1 + (0:149) %/% 50)
However, a problem arises when I try to mix numeric and factor variables together:
group <- sample( LETTERS[1:4], 100, replace=TRUE, prob=c(0.25, 0.25, 0.25, 0.25) )
d = matrix(a,b, group)
parcoord(d[, c(3, 1, 2)], col = 1 + (0:149) %/% 50)
Error in x - min(x, na.rm = TRUE): non-numeric argument to binary operator
I am just curious. Can this problem be resolved? Or is it simply impossible to make such a plot using numeric and factor variables together?
I saw a previous stackoverflow post over here where a similar plot is made using numeric and factor variables: How to plot parallel coordinates with multiple categorical variables in R
However, I am using a computer with no USB port or internet access - I have a pre-installed version of R with limited libraries (I have plotly, ggplot2, dplyr, MASS ... I don't have ggally or tidyverse) and was looking for a way to do this only with the parcoord() function.
Does anyone have any ideas if this can be done?
Thanks
Thanks
One option is to label rows of the matrix using a factor and use that on the plot, e.g.
library(MASS)
set.seed(300)
par(xpd=TRUE)
par(mar=c(4, 4, 4, 6))
a = rnorm(12, 10, 10)
b = rnorm(12, 10, 5)
c = rnorm(12, 5, 10)
group <- sample(c("#FF9289", "#FF8AFF", "#00DB98", "#00CBFF"),
12, replace=TRUE)
d = cbind(a, b, c)
rownames(d) <- group
parcoord(d[, c(3, 1, 2)], col = group)
title(main = "Plot", xlab = "Variable", ylab = "Values")
axis(side = 2, at = seq(0, 1, 0.1),
tick = TRUE, las = 1)
legend(3.05, 1, legend = c("A", "B", "C", "D"), lty = 1,
col = c("#FF9289", "#FF8AFF", "#00DB98", "#00CBFF"))
EDIT
Thanks for the additional explanation. What you want does make sense, but unfortunately it doesn't look like it will work as I expected. I tried to make a plot using an ordered factor as the middle variable (per https://pasteboard.co/JKK4AUD.jpg) but got the same error ("non-numeric argument to binary operator").
One way I thought of doing it is to recode the factor as a number (e.g. "Var_1" -> 0.2, "Var_2" -> 0.4) as below:
library(MASS)
set.seed(123)
par(xpd=TRUE)
par(mar=c(4, 4, 4, 6))
a = rnorm(12, 10, 10)
b = c(rep("Var_1", 3),
rep("Var_2", 3),
rep("Var_3", 3),
rep("Var_4", 3))
c = rnorm(12, 5, 10)
group <- c(rep("#FF9289", 3),
rep("#FF8AFF", 3),
rep("#00DB98", 3),
rep("#00CBFF", 3))
d = data.frame("A" = a,
"Factor" = b,
"C" = c,
"Group" = group)
d$Factor <- sapply(d$Factor, switch,
"Var_1" = 0.8,
"Var_2" = 0.6,
"Var_3" = 0.4,
"Var_4" = 0.2)
parcoord(d[, c(1, 2, 3)], col = group)
title(main = "Plot", xlab = "Variable", ylab = "Values")
axis(side = 2, at = seq(0, 1, 0.1),
tick = TRUE, las = 1)
legend(3.05, 1, legend = c("A", "B", "C", "D"), lty = 1,
col = c("#FF9289", "#FF8AFF", "#00DB98", "#00CBFF"))
mtext(text = "Var 1", side = 1, adj = 0.6, padj = -30)
mtext(text = "Var 3", side = 1, adj = 0.6, padj = -12)
mtext(text = "Var 2", side = 1, adj = 0.6, padj = -21)
mtext(text = "Var 4", side = 1, adj = 0.6, padj = -3)

R Highcharter specify continuous x and y axis

I am a bit confused with use of highcharter hc_add_series function.
I am trying to create a plot where I need to specify both x and y axis, where x axis are continuous. I have a data-frame, for example:
df_plot <- cbind(
seq(0, 1, by = 0.1),
sample(seq(from = 100, to = 300, by = 10), size = 11, replace = TRUE),
sample(seq(from = 1, to = 100, by = 9), size = 11, replace = TRUE),
sample(seq(from = 50, to = 60, by = 2), size = 11, replace = TRUE),
sample(seq(from = 100, to = 130, by = 1), size = 1, replace = TRUE)
) %>%
as.data.frame()
names(df_plot) <- c("x", "a", "b", "c", "d")
I saw this example that works
highchart() %>%
hc_add_series(data = purrr::map(4:8, function(x) list(x, x)), color = "blue")
So i tried:
df_plot1 <- Map(cbind, split.default(df_plot[-1], names(df_plot)[-1]), x=df_plot[1])
highchart() %>%
hc_add_series(data = df_plot1[[1]]) %>%
hc_add_series(data = df_plot1[[2]], yAxis = 1) %>%
hc_yAxis_multiples(
list(lineWidth = 3, lineColor='#7cb5ec', title=list(text="First y-axis")),
list(lineWidth = 3, lineColor="#434348", title=list(text="Second y-axis")))
However, I am getting "No data to display" on the plot, so I obviously went wrong somewhere.
Also, I cannot use hchart function, as I need have multiple y axis
After reading docs about split.default it Divide into Groups and Reassemble, however you need to access the variable you want to plot, e.g. df_plot1[[1]$a, like so:
library(highcharter)
df_plot <- cbind(
seq(0, 1, by = 0.1),
sample(seq(from = 100, to = 300, by = 10), size = 11, replace = TRUE),
sample(seq(from = 1, to = 100, by = 9), size = 11, replace = TRUE),
sample(seq(from = 50, to = 60, by = 2), size = 11, replace = TRUE),
sample(seq(from = 100, to = 130, by = 1), size = 1, replace = TRUE)
) %>% as.data.frame()
names(df_plot) <- c("x", "a", "b", "c", "d")
df_plot1 <- Map(cbind, split.default(df_plot[-1], names(df_plot)[-1]), x=df_plot[1])
highchart() %>%
hc_xAxis(categories = df_plot1[[1]]$x) %>%
hc_add_series(data = df_plot1[[1]]$a) %>%
hc_add_series(data = df_plot1[[2]]$b, yAxis = 1) %>%
hc_yAxis_multiples(
list(lineWidth = 3, lineColor='#7cb5ec', title=list(text="First y-axis")),
list(lineWidth = 3, lineColor="#434348", title=list(text="Second y-axis")))
not sure if this can help you,
library(tidyr)
df_plot2 <- gather(df_plot, group, y, -x)
hchart(df_plot2, "line", hcaes(x, y, group = group))
hchart(df_plot2, "line", hcaes(x, y, group = group), yAxis = 0:3) %>%
hc_yAxis_multiples(
list(lineWidth = 3, title=list(text="First y-axis")),
list(lineWidth = 3, title=list(text="Second y-axis")),
list(lineWidth = 3, title=list(text="3rd y-axis")),
list(lineWidth = 3, title=list(text="4th y-axis"))
)

How to assign name to every circle in a Venn diagram using R (Venndiagram package)

I would assign a name for every circle in a Venn diagram. I have tried to change options in category but seems this is the only set I can use. I attach my code, please where is the wrong part?
goterm3 = c(1,2,3,4,5,6)
goterm2 =c(2,2,3,4,3,5)
goterm1=c(4,5,3,2,4,3,2,4)
int12 = intersect(goterm1, goterm2)
int13 = intersect(goterm1, goterm3)
int23 = intersect(goterm2, goterm3)
intall = intersect(int12, goterm3)
require(VennDiagram)
venn.plot = draw.triple.venn(length(goterm1), length(goterm2), length(goterm3),
length(int12), length(int23), length(int13),length(intall),
category = rep("ORG1, ORG2,Org",3) ,rotation = 1, reverse = FALSE, euler.d = FALSE,
scaled = FALSE, lwd = rep(2, 3), lty = rep("solid", 3),
col = rep("black", 3), fill = c("blue", "red", "green"),
alpha = rep(0.5, 3),
label.col = rep("black", 7), cex = rep(1, 7), fontface = rep("plain", 7),
fontfamily = rep("serif", 7), cat.pos = c(0, 0, 180),
cat.dist = c(0.05, 0.05, 0.025), cat.col = rep("black", 3),
cat.cex = rep(1, 3), cat.fontface = rep("plain", 3),
cat.fontfamily = rep("serif", 3),
cat.just = list(c(0.5, 1), c(0.5, 1), c(0.5, 0)), cat.default.pos = "outer",
cat.prompts = FALSE, rotation.degree = 0, rotation.centre = c(0.5, 0.5),
ind = TRUE, sep.dist = 0.05, offset = 0)
This is what I get and it does have the same labels as your categories (after I unmangled the string values for the categories:
category = c("ORG1", "ORG2","Org") # no rep needed and proper quotes

Resources