offsetting the mean on a scatter plot? - r

the figure wth offset points but mean in the middle
I'm plotting two sets of data on the same plot, distinguishing the two sets by using different pch and by offsetting them. I also want to plot the mean of both sets of data but so far I've only been able to offset the data points, not the means. This is my code
points(jitter(as.numeric(gen$genord)-0.1,0.1),ai$propaiacts, pch=15,col="dimgray",cex=1)
points(jitter(as.numeric(ugen$genord)+0.1,0.1),uai$propuaiacts, pch=6)
s=split(gen$propaiacts,gen$gencode)
points(jitter(sapply(s, mean)+0.5,0.5),pch="__", cex=2)
s=split(ugen$propuaiacts,ugen$gencode)
points(jitter(sapply(s, mean)-0.1,0.1),pch="__", cex=2)
this is the relevant data:
dput(c(gen$genord,gen$propaiacts))
c(3, 1, 2, 3, 3, 1, 1, 2, 1, 2, 1, 2, 13.5986733, 6.6115702,
9.2198582, 0.6001775, 1.0177719, 6.4348071, 10.0849649, 16.5116934,
11.00971, 14.2514897, 4.366077, 7.3884464)
> dput(c(ugen$ugenord,ugen$propuaiacts))
c(3, 1, 2, 3, 3, 1, 1, 2, 1, 2, 1, 2, 1, 9.4512195, 6.3064133,
7.2121554, 0.6486974, 1.0140406, 5.9735066, 10.076442, 12.5423729,
9.6563923, 13.3744272, 4.4930535, 5.3341665, 21.0191083)

using your code and dataset was difficult, so I will use the iris dataset and hopefully it will help you started. As an alternative to your base R, I used ggplot2. I only converted the data from wide to long. And then I just added position = position_dodge(width = 1) to the geom_point() expression. To add the mean for each group (black dot), I summarised the dataset iris_melt. Hope it will help you to get what you want.
iris_melt <- melt(iris, id.vars=c("Species"))
iris_melt_s <- ddply(iris_melt, c("Species", "variable"), summarise,
meanv = mean(value))
iris_melt <- melt(iris, id.vars=c("Species"))
ggplot(data=iris_melt, aes(x=variable, y=value, group=Species, color=Species, shape=Species)) +
geom_point(position = position_dodge(width = 0.5)) +
geom_point(data=iris_melt_s, aes(x=variable, y=meanv, group=Species, color=Species), color="black", position = position_dodge(width = 0.5))

i realised that I could simply specify the number of categories on the x and then shift it. It's a bit manual, but it worked for now. s=split(ai$propaiacts,ai$recallord) points(c(1,2,3)-0.1,sapply(s, mean), pch="__", cex=2)

Related

Add custom spacing or gaps between bars in barplot ggplot

Is there a way to add custom spacing between bars in a barplot using ggplot function geom_col()?
I want to recreate something like this but in ggplot:
x <- c(2, 4, 7, 5)
barplot(x, space = c(0, 2, 1, 3))
data.frame(y=c(2, 4, 7, 5), x=cumsum(c(0, 2, 1, 3))) |>
ggplot(aes(x, y)) +
geom_col() +
scale_x_continuous()

Stacked bar plot in R with the positive and negative values

I would like to plot a stacked bar plot in R and my data looks as such:
This table is the values against date and as it can be seen, there are repetitive dates with different sides. I would like to plot a bar plot using this data.
combined = rbind(x,y)
combined = combined[order(combined$Group.1),]
barplot(combined$x,main=paste("x vs y Breakdown",Sys.time()),names.arg = combined$Group.1,horiz = TRUE,las=2,xlim=c(-30,30),col = 'blue',beside = True)
Want a stacked plot where I can see the values against dates. How do change my code?
You can easily create this figure with ggplot2.
Here a piece of code for you using a data frame similar to what you have:
library(ggplot2)
my_data <- data.frame(
date = factor(c(1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8)),
x = c(-2, 14, -8, -13, 3, -4, 9, 8, 3, -4, 8, -1)
)
g <- ggplot(my_data, aes(x = date, y = x)) +
geom_bar(
stat = "identity", position = position_stack(),
color = "white", fill = "lightblue"
) +
coord_flip()
This is the output:
Obviously, the official documentation is a good way to start to understand a bit better how to improve it.

Create a stacked area plot or "stacked" circle plot

Purpose
Create a stacked area plot or a "stacked" circle plot (see picture). Pie chart is not desired.
Data and code of a bar plot
#Data set:
Numbers 16%
Frosts 2%
Doors 6%
Shelfs 10%
Earning -3%
par(mai=c(2, 1, 1, 1), lwd=2)
barplot(as.numeric(c(16, 2, 6, 10, -3)), col = c("lightblue"), main="Bar plot",
names.arg=c("Numbers","Frosts","Earning", "Doors","Shelfs"), xpd=TRUE, las=2, lwd=2,
axes=FALSE, axis.lty=1, cex.axis=1, cex.names=1, cex.main=1, ylim=c(-4, 18), xlim=c(0, 5))
Two output options
This should get you most of the way there
library(ggplot2)
df<- data.frame(value=as.numeric(c(16, 2, 6, 10, -3)),
cat=c("Numbers","Frosts","Earning","Doors","Shelfs"))
ggplot(df[order(df$value),], aes(x=1, y=abs(value), fill=factor(ifelse(value>0, 0, 1)))) +
geom_bar(stat="identity", colour="grey") +
geom_text(aes(label=paste(cat, value)), position = "stack", vjust = 3) +
scale_fill_manual(values=c("white", "red"))
ggplot(df[order(df$value),], aes(x=1, y=abs(value), fill=factor(ifelse(value>0, 0, 1)))) +
geom_bar(stat="identity", colour="grey") +
geom_text(aes(label=paste(cat, value)), position = "stack", vjust = -1) +
scale_fill_manual(values=c("white", "red")) +
coord_polar()
You may need to fiddle around with the vjust values to change the position of the labels, or calculate a custom y mapping for them, but it's a good start.
You can try to work with this:
library(ggplot2)
data<-data.frame(Name=c("Earning","Frosts","Doors","Shelfs","Numbers"),Val=c(1,2,6,10,16))
ggplot(data,aes(x=factor(1),y=Val,fill=Name))+
geom_bar(stat="identity",width=1)+coord_polar()
Just change color palette and add text wherever you want (and of course first value in Val column if it's too big on the plot - it corresponds to your negative value)
The topmost of the "Related" links to the right should give you most of the info you need to construct a stacked bar plot, but adapted for your use it would be something like this:
# A vertical matrix containing the values
md <- matrix(c(-3, 16, 2, 6, 10), ncol=1)
d <- barplot(md, col=c(2, rep(0, 4)))
# Finding the vertical position for the labels
ypos <- apply(md, 2, cumsum)
ypos <- ypos - md/2
ypos <- t(ypos)
# I haven't checked if the values and names match
text(d/3, ypos, adj=c(0, NA),
paste(c("Earning","Numbers","Frosts","Doors","Shelfs"), md, sep=": "))

How to make a grouped barchart with two groups on x-axis

I have a data that looks like this
Name, Clusters, incorrectly_classified
PCA, 2, 34.37
PCA, 6, 60.80
ICA2, 2, 37.89
ICA6, 2, 33.20
ICA2, 6, 69.66
ICA6, 6, 60.54
RP2, 2, 32.94
RP4, 2, 33.59
RP6, 2, 31.25
RP2, 6, 68.75
RP4, 6, 61.58
RP6, 6, 56.77
I would like to create a barplot for the above data that is similar to this plot I drew
x axis will have two numbers 2 or 6. Y-axis will have incorrectly_classified and the Name will be plotted for each 2 or 6. Each Name for each group (2 or 6) would be colored consistently among the two groups.
Is this possible to achieve with barchart? If not with barchart, then what is a good way to plot this data
I think the following is what you are after.
ggplot(data = mydf, aes(x = factor(Clusters), y = incorrectly_classified, fill = Name)) +
geom_bar(stat = "identity", position = "dodge") +
labs(x = "Clusters", y = "Incorrectly classified")
This can be done with barplot.
An example:
counts <- table(mtcars$vs, mtcars$gear)
barplot(counts, main="Car Distribution by Gears and VS",
xlab="Number of Gears", col=c("darkblue","red"),
legend = rownames(counts), beside=TRUE)
EDIT
I will also work my answer out to demonstrate the barplot option (although ggplot is much cooler :-) ):
if df is your dataframe:
dfwide<-reshape(df,timevar="Clusters",v.names="incorrectly_classified",idvar="Name",direction="wide")
rownames(dfwide) <- dfwide$Name
dfwide$Name<-NULL
names(dfwide)[names(dfwide)=="incorrectly_classified.2"] <- "2"
names(dfwide)[names(dfwide)=="incorrectly_classified.6"] <- "6"
dfwide<-as.matrix(dfwide)
barplot(dfwide, main="Your Graph",
xlab="Clusters",ylab="incorrectly_classified",col=c("darkblue","red","orange","green","purple","grey"),
legend = rownames(dfwide), beside=TRUE,args.legend = list(x = "topleft", bty = "n", inset=c(0.15, -0.15)))

Trajectory Tree

I'm looking to plot something similar to this in R. Can this be this be done with ggplot or some other package?
Found on the following blog:
http://intelligenttradingtech.blogspot.com/2011/07/pattern-recognition-forward-boxplot.html
Here is how to construct the graph using ggplot2.
I constructed the data manually, by specifying the coordinates of each line start and end position. An improvement would obviously be to automate this using an algorithm. Since this wasn't the question, I didn't attempt to solve this too.
Create the data:
arrowdata <- c(
0, 0, 1, 0,
1, 1, 2, 1,
1, -1, 2, -1,
2, 1.5, 3, 1.5,
2, 0.5, 3, 0.5
)
linesdata <- c(
1, 0, 1, 1,
1, 0, 1, -1,
2, 1, 2, 1.5,
2, 1, 2, 0.5
)
labeldata <- data.frame(
x = c(0.5, 1.5, 2.5),
y = c(0, 1, 1.5),
labels=c("Label 1", "Label2", "Label 3")
)
adat <- as.data.frame(matrix(arrowdata, ncol=4, byrow=TRUE))
ldat <- as.data.frame(matrix(linesdata, ncol=4, byrow=TRUE))
Load the ggplot2 and grid packages, then plot:
library(ggplot2)
library(grid) # For arrow() function
ggplot() +
geom_segment(
data=adat,
aes(x=V1, y=V2, xend=V3, yend=V4),
arrow=arrow(length = unit(0.05, "npc"), type="closed"),
col="blue"
) +
geom_segment(
data=ldat,
aes(x=V1, y=V2, xend=V3, yend=V4),
col="blue"
) +
geom_text(data=labeldata, aes(x, y, label=labels),
size=8, vjust=-0.2, col="blue"
) +
theme_bw() +
opts(
axis.text.x=theme_blank(),
axis.text.y=theme_blank(),
axis.ticks=theme_blank(),
axis.title.x=theme_blank(),
axis.title.y=theme_blank(),
panel.grid.major=theme_blank(),
panel.border=theme_blank()
) +
coord_cartesian(ylim=c(-1.5, 2)) # Create some additional space for labels
You might find something at http://addictedtor.free.fr/graphiques/ . There's an amazing variety of graphs and charts there. Now, it's easy enough to write a little code using the base plot and graphics::arrow functions that will draw lines between the vertices. E.g.,
arrows(0,1,0,0)
lines(c(1,1),c(-.5,.5))
arrows(1,2,.5,.5)
and so on. Do you have a requirement to size or place the branches based on data, or is this a purely qualitative tree?

Resources