I have done a clustering dendrogram following a previous code I found online, but the x-axis of is not being shown in the graph. I would like to have the dissimilarity value shown in the x-axis, but I have not been successful.
females<-cervidae[cervidae$Sex=="female",]
dstf <- daisy(females[,9:14], metric = "euclidean", stand = FALSE)
hcaf <- hclust(dstf, method = "ave")
k <- 3
clustf <- cutree(hcaf,k=k) # k clusters
dendrf <- dendro_data(hcaf, type="rectangle") # convert for ggplot
clust.dff <- data.frame(label=rownames(females), cluster=factor(clustf),
females$Genus, females$Species)
dendrf[["labels"]] <- merge(dendrf[["labels"]],clust.dff, by="label")
rectf <- aggregate(x~cluster,label(dendrf),range)
rectf <- data.frame(rectf$cluster,rectf$x)
ymax <- mean(hcaf$height[length(hcaf$height)-((k-2):(k-1))])
fem=ggplot() +
geom_segment(data=segment(dendrf), aes(x=x, y=y, xend=xend, yend=yend)) +
geom_text(data=label(dendrf), aes(x, y, label= females.Genus, hjust=0,
color=females.Genus),
size=3) +
geom_rect(data=rectf, aes(xmin=X1-.3, xmax=X2+.3, ymin=0, ymax=ymax),
color="red", fill=NA)+
coord_flip() + scale_y_reverse(expand=c(0.2, 0)) +
theme_dendro() + scale_color_discrete(name="Genus") +
theme(legend.position="none")
Here is how my dendrogram looks:
Your code included theme_dendro(), which is described in its help file as:
Sets most of the ggplot options to blank, by returning blank theme
elements for the panel grid, panel background, axis title, axis text,
axis line and axis ticks.
You force the x-axis line / text / ticks to be visible in theme():
ggplot() +
geom_segment(data=segment(dendrf), aes(x=x, y=y, xend=xend, yend=yend)) +
geom_text(data=label(dendrf), aes(x, y, label= label, hjust=0,
color=cluster),
size=3) +
geom_rect(data=rectf, aes(xmin=X1-.3, xmax=X2+.3, ymin=0, ymax=ymax),
color="red", fill=NA)+
coord_flip() +
scale_y_reverse(expand=c(0.2, 0)) +
theme_dendro() +
scale_color_discrete(name="Cluster") +
theme(legend.position="none",
axis.text.x = element_text(), # show x-axis labels
axis.ticks.x = element_line(), # show x-axis tick marks
axis.line.x = element_line()) # show x-axis lines
(This demonstration uses a built-in dataset, since I'm not sure what's cervidae. Code used to create this is reproduced below:)
library(cluster); library(ggdendro); library(ggplot2)
hcaf <- hclust(dist(USArrests), "ave")
k <- 3
clustf <- cutree(hcaf,k=k) # k clusters
dendrf <- dendro_data(hcaf, type="rectangle") # convert for ggplot
clust.dff <- data.frame(label=rownames(USArrests),
cluster=factor(clustf))
dendrf[["labels"]] <- merge(dendrf[["labels"]],clust.dff, by="label")
rectf <- aggregate(x~cluster,label(dendrf),range)
rectf <- data.frame(rectf$cluster,rectf$x)
ymax <- mean(hcaf$height[length(hcaf$height)-((k-2):(k-1))])
Related
How can I display two plots in one row with R function ggarrange() so that they have the same dimensions, in particular the same height?
In this example, the second plot is a bit higher than the first plot. I would like to increase the size of a1_plot, so that it matches the size of a2_plot.
# required packages
library(ggplot2)
library(ggbreak)
library(directlabels)
library(ggpubr)
# make dataframe
df1 <- data.frame(first_column=c("value_1","value_2","value_3","value_4","value_4","value_5"),
second_column=c("123","123","325","325","656","656"),
third_column=c(12,13,1,19,200,360),
fourth_column=c(1,124,155,3533,5533,6666))
# plot 1
a1_plot <-
ggplot(df1, aes(x=third_column, y=fourth_column, colour=second_column)) +
scale_x_continuous(breaks = c(0,50,100,150,200,250,300)) +
ylab("Fourth column")+ xlab("Third column") +
scale_x_break(breaks = c(210,400)) +
geom_dl(mapping=aes(x=third_column, y=fourth_column, label=second_column),
method = list(dl.trans(x = x + 0.1), dl.combine("last.points"))) +
theme(legend.position = "none")
# plot 2
a2_plot <-
ggplot(data=df1)+
geom_point(aes(x=second_column, y=fourth_column) +
xlab("X axis")+ ylab("Y axis") +
theme(legend.position = "none")
# merge plot1 and plot2
ggarrange(print(a1_plot), print(a2_plot), labels = c('a1', 'a2'))
I was unable to change the height of plot 1. By adjusting the margins of plot 2, the problem has been solved.
theme(legend.position = "none", plot.margin = unit(x=c(3.6,5,3.9,0), units = "mm"))
I've created a plot (below) and basically want the left and right ends of each facet to state "Ov" and "Cx." I've tried using scale_x_continuous but the issue is that the x-axis for each facet is different.
What I have right now (image):
What I'd like to get ideally:
all_prm %>% ggplot(aes(y_coord, prominence)) +
geom_point() +
facet_wrap(~interaction(ms, sample), scales="free_x") +
scale_x_continuous(breaks=c(10000), labels=c("Ov")) +
theme(
axis.title.y=element_text(margin=margin(r=7)),
axis.title.x=element_text(margin=margin(t=7)),
panel.background = element_rect(fill='white', color='grey10')) +
xlab("Oviduct-Cervical Axis") +
ylab("Prominence")
You can use a custom function to set the break points, in this case using the range of the x limit values with an adjustment argument to move the labels away from the axis limits relative to their scale.
Using the iris dataset:
break_range <- function(x, adjust = .025) {
rng <- range(x)
rng + diff(rng) * c(adjust, -adjust)
}
ggplot(iris, aes(Petal.Length, Sepal.Length )) +
geom_point() +
facet_wrap(. ~ Species, nrow = 3, scales="free_x") +
scale_x_continuous(breaks = break_range, labels = c("Ov", "Cx")) +
theme(
axis.title.y=element_text(margin=margin(r=7)),
axis.title.x=element_text(margin=margin(t=7)),
panel.background = element_rect(fill='white', color='grey10'))
I am trying to make a ggplot2 Barplot with broken Y axis using the script provided HERE
My script
library(ggplot2)
dat <- read.csv("expression",header=T, check.names = FALSE)
dat
pd <- position_dodge(0.7) # move them .05 to the left and right
#Function to transform data to y positions
trans <- function(x){pmin(x,2) + 0.05*pmax(x-2,0)}
yticks <- c(0, 1, 2, 10,15,20,25,30)
#Transform the data onto the display scale
dat$mean_t <- trans(dat$value)
dat$sd_up_t <- trans(dat$value + dat$sd)
dat$sd_low_t <- pmax(trans(dat$value - dat$sd),1) #
png("test.png", units="in", family="Times", width=6, height=4, res=300) #pointsize is font size| increase image size to see the key
ggplot(data=dat, aes(x=gene, y=mean_t, group=treatment, fill=treatment)) +
geom_errorbar(aes(ymin=sd_low_t, ymax=sd_up_t),size=.5,
width=.2,
position=position_dodge(0.7)) +
geom_col(position="dodge") +
geom_rect(aes(xmin=0, xmax=4, ymin=2.2, ymax=2.3), fill="white") +
scale_y_continuous(limits=c(0,NA),expand = c(0,0), breaks=trans(yticks), labels=yticks) +
labs(y="Relative titer of CLas")+
theme_classic()
My data looks like this
gene,treatment,value,sd
tar1,EV,1,0.1
tar1,OX6,25.4,3
tar1,OX102,18.3,3
tar2,EV,1,0.1
tar2,OX6,1.6,0.2
tar2,OX102,1.5,0.2
tar3,EV,1,0.1
tar3,OX6,3.98,0.3
tar3,OX102,1.7,0.1
My plot
I have been running through 3 problems
Set maximum on the y-axis is not working.
My error bars are not properly placed.
My y-axis is not covered with white geom_rect
Thanks for your help.
How I can modify the following code to have a plot between x and y (scatter plot) and the fitted values X0.025 and y=X0.975 as the curves (lines) on the plot. (please run plot(m6) to see the plot which I am looking for to make by ggplot)
library(quantregGrowth)
data(growthData)
m6<-gcrq(y~ps(x, lambda=seq(0,100,l=20)), tau=c(0.025,0.975), n.boot=10,
data=growthData)
plot(m6)
I tried to make this plot by ggplot and here is the code:
library(ggplot2)
library(plotly)
temp <- data.frame(m6$fitted)
growthData_b <- cbind(growthData, temp)
a <- ggplot(data=growthData_b, aes(x, y=X0.025)) + geom_line() +
geom_line(data=growthData_b, aes(x, y=X0.975), color = "red") + theme_bw()
Are you looking for this?
ggplot(data=growthData_b, aes(x, y=X0.025)) +
geom_line() +
geom_line(data=growthData_b, aes(x, y=X0.975), color = "red", linetype = 2) +
theme_bw() +
geom_point(aes(x=x, y=y), shape = 1)
I start by giving you my example code:
x <- runif(1000,0, 5)
y <- c(runif(500, 0, 2), runif(500, 3,5))
A <- data.frame("X"=x,"Y"=y[1:500])
B <- data.frame("X"=x,"Y"=y[501:1000])
ggplot() +
stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) +
stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) +
scale_fill_continuous(low="red4", high="#ED1A3A")
It produces the following plot:
Now I want the lower hexagons to follow a different scale. Namely ranging from a dark green to a lighter green. How can I achieve that?
Update:
As you can see from the answers so far, I am asking myself whether there is a solution without using alpha scales. Also, using two plots with no margin or something similar is not an option for my specific application. Though they both are legitimate answers :)
Rather than trying to get two different fill scales in one plot you could alter the colours of the lower values, after the plot has been built. The basic idea is have two plots with the differing fill scales and then copy accross certain details from one plot to the other.
# Base plot
p <- ggplot() +
stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) +
stat_bin_hex(data=B, aes(x=X, y=Y), bins=10)
# Produce two plots with different fill colours
p1 <- p + scale_fill_continuous(low="red4", high="#ED1A3A")
p2 <- p + scale_fill_continuous(low="darkgreen", high="lightgreen")
# Get fill colours for second plot and overwrite the corresponding
# values in the first plot
g1 <- ggplot_build(p1)
g2 <- ggplot_build(p2)
g1$data[[1]][,"fill"] <- g2$data[[1]][,"fill"]
# You can draw this now but there is only one legend
grid.draw(ggplot_gtable(g1))
To have two legends you can join the legends from the two plots together
# Bind the legends from the two plots together
g1 <- ggplot_gtable(g1)
g2 <- ggplot_gtable(g2)
g1$grobs[[grep("guide", g1$layout$name )]] <-
rbind(g1$grobs[[grep("guide", g1$layout$name )]],
g2$grobs[[grep("guide", g2$layout$name )]] )
grid.newpage()
grid.draw(g1)
Giving (from set.seed(10) prior to data generation)
This should provide more or less what you want
ggplot() +
stat_bin_hex(data=A, aes(x=X, y=Y, alpha=..count..), bins=10,fill="green") +
stat_bin_hex(data=B, aes(x=X, y=Y, alpha=..count..), bins=10,fill="red")
To avoid that the grey is disturbing due to the alpha one could underlay the plot with another white plot at the same location and darken the colours a bit, as suggested by the TO in the comments
#just the red to show the impact due to scale_alpha
ggplot() +scale_alpha_continuous(range=c(0.5,1))+ stat_bin_hex(data=A, aes(x=X, y=Y), bins=10,fill="white",show.legend = TRUE) +
+ stat_bin_hex(data=A, aes(x=X, y=Y, alpha=..count..), bins=10,fill="red",show.legend = TRUE) +
+ stat_bin_hex(data=B, aes(x=X, y=Y, alpha=..count..), bins=10,fill="green", show.legend=TRUE)+guides(fill=FALSE, alpha=FALSE)
An alternative, if you want more options to play with the colours, just create two plots and remove all the space between the two plots when combined with grid.arrange().
p1 <- ggplot() + stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) +
scale_fill_continuous(low="red4", high="#ED1A3A") + xlab("") + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(), plot.margin=unit(c(1,1,-0.5,1), "cm")) + scale_y_continuous(limits = c(2.5, 5.5))
p2 <- ggplot() + stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) + scale_fill_continuous(low="darkgreen", high="green") + theme(plot.margin=unit(c(-0.5,1,1,1), "cm")) + scale_y_continuous(limits = c(-0.5, 2.5))
grid.arrange(p1,p2)