Recreating a ggplot2 geom_point() using base graphics - r

I've the following ggplot2 code and I'd like to use base graphics instead of ggplot2 to generate a similiar output - but I can't seem to find a way to differentiate more than one "attribute" with the normal plot. Am I missing something:
Ggplot2:
ggplot(data.df, aes(x=Axis1, y=Axis2, shape=Plant, color=Type)) +
geom_point()
My plot attempt (the inline help got me quite some way):
data.ma <- as.matrix(data.df)
plot(range(data.ma[,6]), range(data.ma[,7]),xlab="Axis 1",ylab="Axis 2")
points(data.ma[data.ma[,1] == 'Plant1',6],
data.ma[data.ma[,1] == 'Plant1',7], pch=2)
points(data.ma[data.ma[,1] == 'Plant2',6],
data.ma[data.ma[,1] == 'Plant2',7], pch=3)
legend(0,legend=c("Plant1","Plant2"))
This gives me a plot where at least the "Plant" type can be distinguished in the plot, but it does seem far to complicated and I can't figure out how to change the color of all points depending on the "Type" row.
Any suggestions?
Edit - an example with data // where I realize that my first attempt with plot doesn't even give a correct example :( :
library(ggplot2)
data.df <- data.frame(
Plant=c('Plant1','Plant1','Plant1','Plant2','Plant2','Plant2'),
Type=c(1,2,3,1,2,3),
Axis1=c(0.2,-0.4,0.8,-0.2,-0.7,0.1),
Axis2=c(0.5,0.3,-0.1,-0.3,-0.1,-0.8)
)
ggplot(data.df, aes(x=Axis1, y=Axis2, shape=Plant, color=Type)) +
geom_point()
data.ma <- as.matrix(data.df)
plot(range(data.ma[,3]), range(data.ma[,4]),xlab="Axis 1",ylab="Axis 2")
points(data.ma[data.ma[,1] == 'Plant1',3],
data.ma[data.ma[,1] == 'Plant1',4], pch=2)
points(data.ma[data.ma[,1] == 'Plant2',3],
data.ma[data.ma[,1] == 'Plant2',4], pch=3)
legend(0,legend=c("Plant1","Plant2"))

I was just about to post this and then I saw Justin beat to much of it. In any case, this includes some rudimentary legends:
color_foo <- colorRampPalette(c('lightblue','darkblue'))
colors <- color_foo(3)
plot(range(data.df[,3]), range(data.df[,4]),
xlab="Axis 1",ylab="Axis 2",type = "n")
points(data.df$Axis1,data.df$Axis2,
pch=c(3,4)[data.df$Plant],
col = colors[data.df$Type])
legend("topright",legend=c("Plant1","Plant2"),pch = 3:4)
legend("bottomright",legend=c("Type1","Type2","Type3"),
pch = 20,col = colors)

Using base plot and your data set:
with(data.df,
plot(x = Axis1,
y = Axis2,
col = factor(Type),
pch = as.integer(factor(Plant))))
Does that do what you're looking for? I'll leave the legend as an exercise for the reader...

Related

Two plots in one plot with ggplot

I need to create "two plots" in "one plot" with ggplot. I managed to do it with base R as follows:
x=rnorm(10)
y=rnorm(10)*20+100
plot(1:10,rev(sort(x)),cex=2,col='red',ylim=c(0,2.2))
segments(x0=1:10, x1=1:10, y0=1.8,y1=1.8+y/max(y)*.2,lwd=3,col='dodgerblue')
However, I am struggling with ggplot, how can it be done?
Here's one possible translation of that code.
ggplot(data.frame(idx=seq_along(x), x,y)) +
geom_point(aes(idx, rev(sort(x))), col="red") +
geom_segment(aes(x=idx, xend=idx, y=1.8, yend=1.8+y/max(y)*.2), color="dodgerblue")
In general with ggplot2, you can add multiple views of data to a plot by adding additional layers (geoms)
My solution is similar to #MrFlick.
I would always recommend having a plot data frame and referring to the variables from there as you can more easily relate variables to plot aesthetics.
library(tidyverse)
plot_df <- data.frame(x, y) %>%
arrange(-x) %>%
mutate(id = 1:10)
ggplot(plot_df) +
geom_point(aes(id, x), color = "red", pch = 1, size = 5) +
geom_segment(aes(x = id, xend = id, y = 1.8, yend = 1.8+y/max(y)*.2),
lwd = 2, color = 'dodgerblue') +
scale_y_continuous(limits = c(0,2.2)) +
theme_light()
Ultimately, the goal of ggplot is to add aesthetics (in this case, the points and the segments) to form the final plot.
If you'd like to learn more, check out the ggplot cheat sheet and read more on the ideas behind ggplot: https://ggplot2.tidyverse.org/

R ggplot2 could not add legend to graph

I'm using visual studio with R version 3.5.1 where I tried to plot legend to the graph.
f1 = function(x) {
return(x+1)}
x1 = seq(0, 1, by = 0.01)
data1 = data.frame(x1 = x1, f1 = f1(x1), F1 = cumtrapz(x1, f1(x1)) )
However, when I tried to plot it, it never give me a legend!
For example, I used the same code in this (Missing legend with ggplot2 and geom_line )
ggplot(data = data1, aes(x1)) +
geom_line(aes(y = f1), color = "1") +
geom_line(aes(y = F1), color = "2") +
scale_color_manual(values = c("red", "blue"))
I also looked into (How to add legend to ggplot manually? - R
) and many other websites in stackoverflo, and I have tried every single function in https://www.rstudio.com/wp-content/uploads/2016/11/ggplot2-cheatsheet-2.1.pdf
i.e.
theme(legend.position = "bottom")
scale_fill_discrete(...)
group
guides()
show.legend=TRUE
I even tried to use the original plot() and legend() function. Neither worked.
I thought there might be something wrong with the dataframe, but I split them(x2,f1,F1) apart, it still didn't work.
I thought there might be something wrong with IDE, but the code given by kohske acturally plotted legend!
d<-data.frame(x=1:5, y1=1:5, y2=2:6)
ggplot(d, aes(x)) +
geom_line(aes(y=y1, colour="1")) +
geom_line(aes(y=y2, colour="2")) +
scale_colour_manual(values=c("red", "blue"))
What's wrong with the code?
As far as I know, you only have X and Y variables in your aesthetics. Therefore there is no need for a legend. You have xlab and ylab to describe your two lines. If you want to have legends, you should put the grouping in the aesthetics, which might require recoding your dataset
d<- data.frame(x=c(1:5, 1:5), y=c(1:5, 2:6), colorGroup = c(rep("redGroup", 5),
rep("blueGroup", 5)))
ggplot(d, aes(x, y, color = colorGroup )) + geom_line()
This should give you two lines and a legend

Symmetrical histograms

I want to make a number of symmetrical histograms to show butterfly abundance through time. Here's a site that shows the form of the graphs I am trying to create: http://thebirdguide.com/pelagics/bar_chart.htm
For ease, I will use the iris dataset.
library(ggplot2)
g <- ggplot(iris, aes(Sepal.Width)) + geom_histogram(binwidth=.5)
g + coord_fixed(ratio = .003)
Essentially, I would like to mirror this histogram below the x-axis. Another way of thinking about the problem is to create a horizontal violin diagram with distinct bins. I've looked at the plotrix package and the ggplot2 documentation but don't find a solution in either place. I prefer to use ggplot2 but other solutions in base R, lattice or other packages will be fine.
Without your exact data, I can only provide an approximate coding solution, but it is a start for you (if you add more details, I'll be happy to help you tweak the plot). Here's the code:
library(ggplot2)
noSpp <- 3
nTime <- 10
d <- data.frame(
JulianDate = rep(1:nTime , times = noSpp),
sppAbundance = c(c(1:5, 5:1),
c(3:5, 5:1, 1:2),
c(5:1, 1:5)),
yDummy = 1,
sppName = rep(letters[1:noSpp], each = nTime))
ggplot(data = d, aes(x = JulianDate, y = yDummy, size = sppAbundance)) +
geom_line() + facet_grid( sppName ~ . ) + ylab("Species") +
xlab("Julian Date")
And here's the figure.

Keep all plot components same size in ggplot2 between two plots

I would like two separate plots. I am using them in different frames of a beamer presentation and I will add one line to the other (eventually, not in example below). Thus I do not want the presentation to "skip" ("jump" ?) from one slide to the next slide. I would like it to look like the line is being added naturally. The below code I believe shows the problem. It is subtle, but not how the plot area of the second plot is slightly larger than of the first plot. This happens because of the y axis label.
library(ggplot2)
dfr1 <- data.frame(
time = 1:10,
value = runif(10)
)
dfr2 <- data.frame(
time = 1:10,
value = runif(10, 1000, 1001)
)
p1 <- ggplot(dfr1, aes(time, value)) + geom_line() + scale_y_continuous(breaks = NULL) + scale_x_continuous(breaks = NULL) + ylab(expression(hat(z)==hat(gamma)[1]*time+hat(gamma)[4]*time^2))
print(p1)
dev.new()
p2 <- ggplot(dfr2, aes(time, value)) + geom_line() + scale_y_continuous(breaks = NULL) + scale_x_continuous(breaks = NULL) + ylab(".")
print(p2)
I would prefer to not have a hackish solution such as setting the size of the axis label manually or adding spaces on the x-axis (see one reference below), because I will use this technique in several settings and the labels can change at any time (I like reproducibility so want a flexible solution).
I'm searched a lot and have found the following:
Specifying ggplot2 panel width
How can I make consistent-width plots in ggplot (with legends)?
https://groups.google.com/forum/#!topic/ggplot2/2MNoYtX8EEY
How can I add variable size y-axis labels in R with ggplot2 without changing the plot width?
They do not work for me, mainly because I need separate plots, so it is not a matter of aligning them virtically on one combined plot as in some of the above solutions.
haven't tried, but this might work,
gl <- lapply(list(p1,p2), ggplotGrob)
library(grid)
widths <- do.call(unit.pmax, lapply(gl, "[[", "widths"))
heights <- do.call(unit.pmax, lapply(gl, "[[", "heights"))
lg <- lapply(gl, function(g) {g$widths <- widths; g$heights <- heights; g})
grid.newpage()
grid.draw(lg[[1]])
grid.newpage()
grid.draw(lg[[2]])
How about using this for p2:
p2 <- ggplot(dfr2, aes(time, value)) + geom_line() +
scale_y_continuous(breaks = NULL) +
scale_x_continuous(breaks = NULL) +
ylab(expression(hat(z)==hat(gamma)[1]*time+hat(gamma)[4]*time^2)) +
theme(axis.title.y=element_text(color=NA))
This has the same label as p1, but the color is NA so it doesn't display. You could also use color="white".

R: why is my ggplot geom_point() symbol not visible?

I am trying to place a symbol on the lowest point in a certain time series, which I have plotted with ggplot's geom_line. However, the geom_point is not showing up on the plot. I have myself successfully used geom_point for this kind of thing before by following hadley's example here (search for 'highest <- subset' to get the relevant assignment) so I know very well that it can be done. I'm just at a loss to spot what I have done differently here that is causing it not to display. I'm guessing it's something straightforward like a missing argument or similar - easy points for a pair of fresh eyes, I think.
Minimal example follows:
require(ggplot2)
fstartdate <- as.Date('2009-06-01')
set.seed(12345)
x <- data.frame(mydate=seq(as.Date("2003-06-01"), by="month", length.out=103),myval=runif(103, min=180, max=800))
lowest <- subset(x, myval == min(x[x$mydate >= fstartdate,]$myval))
thisplot <- ggplot() +
geom_line(data = x, aes(mydate, myval), colour = "blue", size = 0.7) +
geom_point(data = lowest, size = 5, colour = "red")
print(thisplot)
The point appears if you add the aesthetic:
thisplot + geom_point(
data = lowest,
aes(mydate, myval),
size = 5, colour = "red"
)

Resources