Selectively make one section of axis line thicker in ggplot - r

I would like to plot a density plot using ggplot2, and make one section of the x-axis line thicker (or colored differently).
For example:
interval <- c(x1,x2)
x <- ggplot(df, aes(x=value)) + geom_density()
Is there any way to selectively make the x-axis segment corresponding to (x1,x2) thicker or colored differently? Thanks.

You can use annotate to add a line segment. Setting the y coordinates to -Inf will place it on the x axis. Since your example isn't reproducible, I've demonstrated on the mtcars data:
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() +
annotate(
geom = "segment",
x = 3, xend = 4,
y = -Inf, yend = -Inf,
color = "blue",
size = 5
)

Related

how to decrease relative distance between geom_point() in ggplot

I have a graph that shows a lot of information and I don't want to waste space on whitespace. Is there any way to decrease the plotted distance between points on the x axis. Ideally, I want them to almost touch. I can probably do that changing absolutely every size parameter (dots, axis labels, annotations, legend entries etc) in the plot to something huge but I was wondering if there is an easier way to do so along the lines of position.dodge or so?
Here is an example saved in two different sizes to show that they still have high relative distance:
library(ggplot)
plotdata <- data.frame(my_y = rnorm(3),
my_x = 1:3)
pdf("yourpath/test.pdf",
width = 4, height = 4)
ggplot(plotdata, aes(x = my_x, y = my_y)) + geom_point()
dev.off()
pdf("yourpath/test2.pdf",
width = 2, height = 2)
ggplot(plotdata, aes(x = my_x, y = my_y)) + geom_point()
dev.off()
My answer takes a similar approach to #Quinten but builds in a function for any data:
xmax<-max(plotdata$my_x);ymax=max(plotdata$my_y)
xmin<-min(plotdata$my_x);ymin=min(plotdata$my_y)
pdf("C:/temp/test.pdf",
width = 4, height = 4)
ggplot(plotdata, aes(x = my_x, y = my_y)) + geom_point()+
xlim(xmin-0.1,xmax+0.1)+
ylim(ymin-0.1,ymax+0.1)
dev.off()
If I understand you correctly, you can set limits in coord_cartesian. First plot without limits:
ggplot(plotdata, aes(x = my_x, y = my_y)) + geom_point()
Output:
With limits:
ggplot(plotdata, aes(x = my_x, y = my_y)) + geom_point() + coord_cartesian(xlim=c(-1, 3),
ylim=c(-1.5, 0.5))
Output:
As you can see, they are shown closer together.

how do you specify the x axis in ggplot2 histogram?

I have the following code to plot a histogram using ggplot2.
ggplot(data = plot, aes(x = total_Amg))+
geom_histogram(binwidth = 1, colour = "black", fill = "white") +
facet_wrap(~ gentamicin)
How can I specify what numbers are shown on the x axis of the resulting graph, i.e. show 0 to 8, rather than showing those that was automatically generated (see below)?
+scale_x_continuous(breaks=0:8) should do the trick
Try adding:
+ scale_x_continuous(breaks = 0:8, labels = 0:8)

geom_col does not plot all data points

I have faced a weird behaviour of geom_col and it drives me crazy: basically it does not plot all the data points. When I add geom_point() I clearly see that they are not all represented with a bar.
MWE :
x = sample(1:2000, size = 600, replace = FALSE)
y = 1:600
ggplot(data.frame(x = x, y = y), aes(x,y)) + geom_col() + geom_point()
It is actually plotting all vertical lines, the problem is that it is too thin to show. If you zoom in you will see all the lines.
Try to make the width of the lines thicker, e.g.
ggplot(data.frame(x = x, y = y), aes(x, y)) + geom_col(width = 3) + geom_point()

Different color scale geom_contour and geom_point

I am trying to make a plot using several contour levels with geom_contour. Each of these levels defines a zone onto which I plot points with geom_point. My problem is that I don't manage to have on the same plot a color scale for the points and one for the levels, either the same or another.
MWE:
X <- data.frame(x1 = rnorm(1e4), x2 = rnorm(1e4))
X$z <- sqrt(rowSums(X^2))
X$level <- factor(floor(X$z))
xplot <- yplot <- c(-80:80)/10
df_plot = data.frame(expand.grid(x1=xplot, x2=yplot))
df_plot$z = sqrt(rowSums(df_plot^2))
# plot several contour
ggplot(data = df_plot, aes(x1,x2)) + geom_contour(aes(z=z, color=..level..), breaks = c(1:5))
# plot points with colors corresponding to zone
ggplot(data = X, aes(x1,x2)) + geom_point(aes(color=level))
# plot both
ggplot(data = X, aes(x1,x2)) + geom_point(aes(color=level)) +
geom_contour(data = df_plot, aes(z=z), breaks = 1:5)
On this third plot I'd like to have the levels with the same colors as the points, or at least an other color scale. I've tried to put color= in and out aes but it does not change anything.
thanks
The issue here is that you are mixing a discrete and a continuous colour scale (for the points and the contours, respectively) and ggplot2 uses different defaults for the two. By making the colour scale for the contours discrete as well, you can get the same colours:
ggplot(data = X, aes(x = x1, y = x2)) + geom_point(aes(colour = level)) +
geom_contour(data = df_plot, aes(z = z, colour = factor(..level.. - 1)),
breaks = 0:5, size = 1)
Note that I have reduced the number of points and increased the thickness of the lines to make the lines better visible
This is a slightly long winded way of getting what you want, but you get there in the end.
ggplot(data = X, aes(x1,x2)) +
geom_point(aes(color=level)) + # Now add each contour separately.
geom_contour(data = df_plot, aes(z=z), breaks = 1, colour=rainbow(8)[1]) +
geom_contour(data = df_plot, aes(z=z), breaks = 2, colour=rainbow(8)[2]) +
scale_colour_manual(values=rainbow(8))

Using coord_flip() with facet_wrap(scales = "free_y") in ggplot2 seems to give unexpected facet axis tick marks and tick labels

I am trying to create a faceted plot with flipped co-ordinates where one and only one of the axes are allowed to vary for each facet:
require(ggplot2)
p <- qplot(displ, hwy, data = mpg)
p + facet_wrap(~ cyl, scales = "free_y") + coord_flip()
This plot is not satisfactory to me because the wrong tick marks and tick labels are repeated for each plot. I want tick marks on every horizontal axis not on every vertical axis.
This is unexpected behaviour because the plot implies that the horizontal axis tick marks are the same for the top panels as they are for the bottom ones, but they are not. To see this run:
p <- qplot(displ, hwy, data = mpg)
p + facet_wrap(~ cyl, scales = "fixed") + coord_flip()
So my question is: is there a way to remove the vertical axis tick marks for the right facets and add horizontal axis tick marks and labels to the top facets?
As Paul insightfully points out below, the example I gave can be addressed by swapping x and y in qplot() and avoiding coord_flip(), however this does not work for all geoms for example, if I want a horizontal faceted bar plot with free horizontal axes I could run:
c <- ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar()
c + facet_wrap(~cut, scales = "free_y") + coord_flip()
These facets have a variable horizontal axes but repeated vertical axis tick marks instead of repeated horizontal axes tick marks. I do not think Paul's trick will work here, because unlike scatter plots, bar plots are not rotationally symmetric.
I would be very interested to hear any partial or complete solutions.
Using coord_flip in conjunction with facet_wrap is the problem. First you define a certain axis to be free (the x axis) and then you swap the axis, making the y axis free. Right now this is not reproduced well in ggplot2.
In your first example, I would recommend not using coord_flip, but just swapping the variables around in your call to qplot, and using free_x:
p <- qplot(hwy, displ, data = mpg)
p + facet_wrap(~ cyl, scales = "free_x")
This is the second or third time I have run into this problem myself. I have found that I can hack my own solution by defining a custom geom.
geom_bar_horz <- function (mapping = NULL, data = NULL, stat = "bin", position = "stack", ...) {
GeomBar_horz$new(mapping = mapping, data = data, stat = stat, position = position, ...)
}
GeomBar_horz <- proto(ggplot2:::Geom, {
objname <- "bar_horz"
default_stat <- function(.) StatBin
default_pos <- function(.) PositionStack
default_aes <- function(.) aes(colour=NA, fill="grey20", size=0.5, linetype=1, weight = 1, alpha = NA)
required_aes <- c("y")
reparameterise <- function(., df, params) {
df$width <- df$width %||%
params$width %||% (resolution(df$x, FALSE) * 0.9)
OUT <- transform(df,
xmin = pmin(x, 0), xmax = pmax(x, 0),
ymin = y - .45, ymax = y + .45, width = NULL
)
return(OUT)
}
draw_groups <- function(., data, scales, coordinates, ...) {
GeomRect$draw_groups(data, scales, coordinates, ...)
}
guide_geom <- function(.) "polygon"
})
This is just copying the geom_bar code from the ggplot2 github and then switching the x and y references to make a horizontal barplot in the standard Cartesian coordinators.
Note that you must use position='identity' and possibly also stat='identity' for this to work. If you need to use a position other than identity then you will have to eddit the collide function for it to work properly.
I've just been trying to do a horizontal barplot, and run into this problem where I wanted to scales = "free_x". In the end, it seemed easier to create the conventional (vertical) barplot), rotate the text so that if you tip your head to the left, it looks like the plot that you want. And then, once your plot is completed, rotate the PDF/image output(!)
ggplot(data, aes(x, y)) +
geom_bar(stat = "identity") +
facet_grid(var ~ group, scale = "free", space = "free_x", switch = "both") +
theme(axis.text.y = element_text(angle=90), axis.text.x = element_text(angle = 90),
strip.text.x = element_text(angle = 180))
The main keys to do this are to switch = "both", which moves the facet labels to the other axis, and the element_text(angle=90) which rotates the axis labels and text.

Resources