Spicing Up Native Circular Plot Using ggplot2 [closed] - r

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
CODE UPDATED
I have some angle data from an animal behavior study that I would like to plot for publication using ggplot2. What follows is my current workflow with some example data and how it would look using the generic plot function.
### Create two data frames of random Cartesian coordinates ###
df1 <- data.frame(
x = sample(10, 11, replace = TRUE),
y = sample(10, 11, replace = TRUE))
df2 <- data.frame(
x = sample(10, 11, replace = TRUE),
y = sample(10, 11, replace = TRUE))
### Write a function that converts continuous Cartesian coordinates to velocities ###
get.polar <- function(df)
{
x <- diff(df$x)
y <- diff(df$y)
d <- complex(real = x, imaginary = y)
steps <- data.frame(speed = Mod(d), angle = Arg(d))
steps[-1,] # Deletes the first row as it does not contain an angle measurement
steps$time <- (1:nrow(steps))/30 # generates a time column in seconds (1 data point = 1/30 of a second)
return(steps)
}
df1_polar <- get.polar(df1)
df2_polar <- get.polar(df2)
require(circular)
### Convert angles into an object of type 'circular' ###
df1_rad <- circular(df1_polar$angle, type = 'angles', units = 'radians', zero=0, rotation = "counter")
df2_rad <- circular(df2_polar$angle, type = 'angles', units = 'radians', zero=0, rotation = "counter")
### Convert radians to degrees with a clockwise rotation and zero at "north" ###
df1_deg <- conversion.circular(df1_rad, type = "angles", units = "degrees", zero = pi/2, rotation = "clock")
df2_deg <- conversion.circular(df2_rad, type = "angles", units = "degrees", zero = pi/2, rotation = "clock")
### Convert negative rotations to positive ###
df1_deg[df1_deg < 0] <- df1_deg[df1_deg < 0] + 360
df2_deg[df2_deg < 0] <- df2_deg[df2_deg < 0] + 360
par(pty = "s")
plot(df1_deg, units = "degrees")
ticks.circular(circular(seq(0,(11/6)*pi, pi/6)), zero = pi/2, rotation = "clock", tcl = 0.075)
points(df2_deg, zero = pi/2, rotation = "clock", pch = 16, col = "darkgrey", next.points = -0.2)
# Suggested solution by MLavoie with modifications
temp1 <- data.frame(Exercise = c(1, 1, 1, 1), Name = c(1, 2, 3, 4),
Score = c(90, 180, 270, 360))
temp2 <- data.frame(Name=c(replicate(length(df1_deg), 3)),
Score = c(df1_deg))
temp3 <- data.frame(Name=c(replicate(length(df2_deg), 4)),
Score = c(df2_deg))
temp4 <- data.frame(Name=c(4.8, 4.8, 4.8, 4.8, 4.8, 4.8, 4.8, 4.8),
Score = c(0, 45, 90, 135, 180, 225, 270, 315))
ggplot() +
geom_bar(data = temp1, aes(x = factor(Name), y = Score, fill = factor(Exercise)),
width = 1, stat = 'identity') +
geom_point(data = temp2, aes(x = Name, y = Score),
color = "green", size = 2) +
geom_point(data = temp3, aes(x = Name, y = Score),
color = "red", size = 2) +
geom_point(data = temp4, aes(x = Name, y = Score),
color = "black", shape = 8, size = 2) +
geom_vline(xintercept = 4.8) +
annotate("text", x = 0, y = 0, label = "+", size = 6) +
scale_y_continuous(breaks = c(0, 45, 90, 135, 180, 225, 270, 315)) +
coord_polar(theta = "y", start = 0) +
theme_bw() + ylab("") + xlab("") +
theme(panel.border = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
strip.text = element_blank(),
strip.background = element_blank(),
axis.text.y = element_blank(),
legend.position = "none",
axis.ticks = element_blank()) +
scale_fill_manual(values = c("transparent", "transparent", "transparent", "transparent"))
Some suggestions for turning this rough plot into something publishable using ggplot2?
Thank you!

What about this for a start:
temp <- data.frame(Exercise=c(1, 1, 1, 1), Name=c(1, 2, 3, 4), Score=c(90, 180, 270, 360))
temp2 <- data.frame(Name=c(2.8, 2.8, 2.8, 2.8), Score=c(90, 180, 270, 360))
temp3 <- data.frame(Name=c(4.2, 4.2, 4.2, 4.2), Score=c(90, 180, 270, 360))
temp4 <- data.frame(Name=c(0), Score=c(180))
temp5 <- data.frame(Name=c(4.8, 4.8, 4.8, 4.8, 4.8, 4.8, 4.8, 4.8), Score=c(45, 90, 135, 180, 225, 270, 305, 360))
ggplot() +
geom_bar(data=temp, aes(x = factor(Name), y=Score, fill = factor(Exercise)), width = 1, stat='identity') +
geom_point(data=temp2, aes(x=Name, y=Score), color="grey") +
coord_polar(theta = "y", start=0) +
theme_bw() + ylab("") + xlab("") +
scale_y_continuous(breaks = c(90, 180, 270, 360)) +
theme(panel.border=element_blank(),
panel.grid.minor=element_blank(),
panel.grid.major=element_blank(),
strip.text=element_blank(),
strip.background=element_blank(),
axis.text.y=element_blank(),
legend.position="none",
axis.ticks = element_blank()) +
scale_fill_manual(values = c("transparent", "transparent", "transparent", "transparent")) +
geom_vline(xintercept=4.8) +
geom_point(data=temp4, aes(x=Name, y=Score), color="black", shape=3, size=4) +
geom_point(data=temp3, aes(x=Name, y=Score), color="black") +
geom_point(data=temp5, aes(x=Name, y=Score), color="black", shape=3, size=2)

Related

Can I plot a horizontal bar showing the distribution as as well the cutoff value?

I want to plot a bar like below.
Here is where I am.
attitude <- c('solid_blue', 'leaning_blue', 'toss_up', 'leaning_red', 'solid_red')
n_votes <- c(190, 108, 121, 39, 80)
group <- c(1,1,1,1,1)
df <- rbind(attitude, n_votes, group)
df <- as.data.frame(t(df))
ggplot(data = df) +
geom_bar(stat = 'identity', mapping = aes (x = group, y = n_votes, fill = attitude)) + coord_flip()
where df is like
attitude n_votes group
1 solid_blue 190 1
2 leaning_blue 108 1
3 toss_up 121 1
4 leaning_red 39 1
5 solid_red 80 1
I got a plot like this
The n_votes does not seem to accumulate correctly, how can I correct this?
Now I have this
Dan
Your main problem is because of the way you constructed your data frame, all the columns in it are character vectors. Look:
class(df$n_votes)
#> [1] "character"
It takes less code and gets better results to construct the data frame like this:
attitude <- c('solid_blue', 'leaning_blue', 'toss_up', 'leaning_red', 'solid_red')
n_votes <- c(190, 108, 121, 39, 80)
df <- data.frame(attitude, n_votes, group)
Now using your plot code (except noting that geom_bar(stat = "identity" is a long-hand way of writing geom_col(
ggplot(data = df) +
geom_col(aes(x = group, y = n_votes, fill = attitude)) +
coord_flip()
We get:
Or, if you want to get closer:
attitude <- c('solid_blue', 'leaning_blue', 'toss_up', 'leaning_red', 'solid_red')
n_votes <- c(190, 108, 121, 39, 80)
df <- data.frame(rev(attitude), rev(n_votes), group)
df$attitude <- factor(rev(attitude), levels = attitude)
ggplot(data = df) +
geom_col(aes(x = group, y = n_votes, fill = attitude)) +
scale_fill_manual(values = rev(c("#2558b1", "#77b3dd", "#cbcbcb", "#f3b0a7", "#d95551")),
guide = guide_none()) +
geom_text(check_overlap = TRUE, label = 298, size = 15,
x = 1.8, y = 0, hjust = 0, color = "#2558b1") +
geom_text(check_overlap = TRUE, label = 119, size = 15,
x = 1.8, y = sum(n_votes), hjust = 1, color = "#d95551") +
geom_text(check_overlap = TRUE, label = "Joe Biden\nDEMOCRAT",
size = 5, x = 1.8, y = 60, hjust = 0) +
geom_text(check_overlap = TRUE, label = "Donald J Trump\nREPUBLICAN",
size = 5, x = 1.8, y = sum(n_votes) - 60, hjust = 1) +
geom_text(check_overlap = TRUE, aes(x = group, y = n_votes, label = n_votes),
position = position_stack(vjust = 0.5), size = 5, color = "white") +
geom_segment(aes(x = 0.55, xend = 1.45, y = sum(n_votes)/2, yend = sum(n_votes)/2),
linetype = 2) +
coord_flip() +
theme_classic() +
scale_x_discrete(expand = expansion(add = c(0.7, 0.7))) +
theme(panel.background = element_rect(fill = "#fdf1e5"),
plot.margin = margin(50, 10, 50, 10),
axis.line = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())

Produce an inset in each facet of an R ggplot while preserving colours of the original facet content

I would like to produce a graphic combining four facets of a graph with insets in each facet showing a detail of the respective plot. This is one of the things I tried:
#create data frame
n_replicates <- c(rep(1:10,15),rep(seq(10,100,10),15),rep(seq(100,1000,100),15),rep(seq(1000,10000,1000),15))
sim_years <- rep(sort(rep((1:15),10)),4)
sd_data <- rep (NA,600)
for (i in 1:600) {
sd_data[i]<-rnorm(1,mean=exp(0.1 * sim_years[i]), sd= 1/n_replicates[i])
}
max_rep <- sort(rep(c(10,100,1000,10000),150))
data_frame <- cbind.data.frame(n_replicates,sim_years,sd_data,max_rep)
#do first basic plot
library(ggplot2)
plot1<-ggplot(data=data_frame, aes(x=sim_years,y=sd_data,group =n_replicates, col=n_replicates)) +
geom_line() + theme_bw() +
labs(title ="", x = "year", y = "sd")
plot1
#make four facets
my_breaks = c(2, 10, 100, 1000, 10000)
facet_names <- c(
`10` = "2, 3, ..., 10 replicates",
`100` = "10, 20, ..., 100 replicates",
`1000` = "100, 200, ..., 1000 replicates",
`10000` = "1000, 2000, ..., 10000 replicates"
)
plot2 <- plot1 +
facet_wrap( ~ max_rep, ncol=2, labeller = as_labeller(facet_names)) +
scale_colour_gradientn(name = "number of replicates", trans = "log",
breaks = my_breaks, labels = my_breaks, colours = rainbow(20))
plot2
#extract inlays (this is where it goes wrong I think)
library(ggpmisc)
library(tibble)
library(dplyr)
inset <- tibble(x = 0.01, y = 10.01,
plot = list(plot2 +
facet_wrap( ~ max_rep, ncol=2, labeller = as_labeller(facet_names)) +
coord_cartesian(xlim = c(13, 15),
ylim = c(3, 5)) +
labs(x = NULL, y = NULL, color = NULL) +
scale_colour_gradient(guide = FALSE) +
theme_bw(10)))
plot3 <- plot2 +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = inset, aes(npcx = x, npcy = y, label = plot)) +
annotate(geom = "rect",
xmin = 13, xmax = 15, ymin = 3, ymax = 5,
linetype = "dotted", fill = NA, colour = "black")
plot3
That leads to the following graphic:
As you can see, the colours in the insets are wrong, and all four of them appear in each of the facets even though I only want the corresponding inset of course. I read through a lot of questions here (to even get me this far) and also some examples in the ggpmisc user guide but unfortunately I am still a bit lost on how to achieve what I want. Except maybe to do it by hand extracting four insets and then combining them with plot2. But I hope there will be a better way to do this. Thank you for your help!
Edit: better graphic now thanks to this answer, but problem remains partially unsolved:
The following code does good insets, but unfortunately the colours are not preserved. As in the above version each inset does its own rainbow colours anew instead of inheriting the partial rainbow scale from the facet it belongs to. Does anyone know why and how I could change this? In comments I put another (bad) attempt at solving this, it preserves the colors but has the problem of putting all four insets in each facet.
library(ggpmisc)
library(tibble)
library(dplyr)
# #extract inlays: good colours, but produces four insets.
# fourinsets <- tibble(#x = 0.01, y = 10.01,
# x = c(rep(0.01, 4)),
# y = c(rep(10.01, 4)),
# plot = list(plot2 +
# facet_wrap( ~ max_rep, ncol=2) +
# coord_cartesian(xlim = c(13, 15),
# ylim = c(3, 5)) +
# labs(x = NULL, y = NULL, color = NULL) +
# scale_colour_gradientn(name = "number of replicates", trans = "log", guide = FALSE,
# colours = rainbow(20)) +
# theme(
# strip.background = element_blank(),
# strip.text.x = element_blank()
# )
# ))
# fourinsets$plot
library(purrr)
pp <- map(unique(data_frame$max_rep), function(x) {
plot2$data <- plot2$data %>% filter(max_rep == x)
plot2 +
coord_cartesian(xlim = c(12, 14),
ylim = c(3, 4)) +
labs(x = NULL, y = NULL) +
theme(
strip.background = element_blank(),
strip.text.x = element_blank(),
legend.position = "none",
axis.text=element_blank(),
axis.ticks=element_blank()
)
})
#pp[[2]]
inset_new <- tibble(x = c(rep(0.01, 4)),
y = c(rep(10.01, 4)),
plot = pp,
max_rep = unique(data_frame$max_rep))
final_plot <- plot2 +
geom_plot_npc(data = inset_new, aes(npcx = x, npcy = y, label = plot, vp.width = 0.3, vp.height =0.6)) +
annotate(geom = "rect",
xmin = 12, xmax = 14, ymin = 3, ymax = 4,
linetype = "dotted", fill = NA, colour = "black")
#final_plot
final_plot then looks like this:
I hope this clarifies the problem a bit. Any ideas are very welcome :)
Modifying off #user63230's excellent answer:
pp <- map(unique(data_frame$max_rep), function(x) {
plot2 +
aes(alpha = ifelse(max_rep == x, 1, 0)) +
coord_cartesian(xlim = c(12, 14),
ylim = c(3, 4)) +
labs(x = NULL, y = NULL) +
scale_alpha_identity() +
facet_null() +
theme(
strip.background = element_blank(),
strip.text.x = element_blank(),
legend.position = "none",
axis.text=element_blank(),
axis.ticks=element_blank()
)
})
Explanation:
Instead of filtering the data passed into plot2 (which affects the mapping of colours), we impose a new aesthetic alpha, where lines belonging to the other replicate numbers are assigned 0 for transparency;
Use scale_alpha_identity() to tell ggplot that the alpha mapping is to be used as-is: i.e. 1 for 100%, 0 for 0%.
Add facet_null() to override plot2's existing facet_wrap, which removes the facet for the inset.
Everything else is unchanged from the code in the question.
I think this will get you started although its tricky to get the size of the inset plot right (when you include a legend).
#set up data
library(ggpmisc)
library(tibble)
library(dplyr)
library(ggplot2)
# create data frame
n_replicates <- c(rep(1:10, 15), rep(seq(10, 100, 10), 15), rep(seq(100,
1000, 100), 15), rep(seq(1000, 10000, 1000), 15))
sim_years <- rep(sort(rep((1:15), 10)), 4)
sd_data <- rep(NA, 600)
for (i in 1:600) {
sd_data[i] <- rnorm(1, mean = exp(0.1 * sim_years[i]), sd = 1/n_replicates[i])
}
max_rep <- sort(rep(c(10, 100, 1000, 10000), 150))
data_frame <- cbind.data.frame(n_replicates, sim_years, sd_data, max_rep)
# make four facets
my_breaks = c(2, 10, 100, 1000, 10000)
facet_names <- c(`10` = "2, 3, ..., 10 replicates", `100` = "10, 20, ..., 100 replicates",
`1000` = "100, 200, ..., 1000 replicates", `10000` = "1000, 2000, ..., 10000 replicates")
Get overall plot:
# overall facet plot
overall_plot <- ggplot(data = data_frame, aes(x = sim_years, y = sd_data, group = n_replicates, col = n_replicates)) +
geom_line() +
theme_bw() +
labs(title = "", x = "year", y = "sd") +
facet_wrap(~max_rep, ncol = 2, labeller = as_labeller(facet_names)) +
scale_colour_gradientn(name = "number of replicates", trans = "log", breaks = my_breaks, labels = my_breaks, colours = rainbow(20))
#plot
overall_plot
which gives:
Then from the overall plot you want to extract each plot, see here. We can map over the list to extract one at a time:
pp <- map(unique(data_frame$max_rep), function(x) {
overall_plot$data <- overall_plot$data %>% filter(max_rep == x)
overall_plot + # coord_cartesian(xlim = c(13, 15), ylim = c(3, 5)) +
labs(x = NULL, y = NULL) +
theme_bw(10) +
theme(legend.position = "none")
})
If we look at one of these (I've removed the legend) e.g.
pp[[1]]
#pp[[2]]
#pp[[3]]
#pp[[4]]
Gives:
Then we want to add these inset plots into a dataframe so that each plot has its own row:
inset <- tibble(x = c(rep(0.01, 4)),
y = c(rep(10.01, 4)),
plot = pp,
max_rep = unique(data_frame$max_rep))
Then merge this into the overall plot:
overall_plot +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = inset, aes(npcx = x, npcy = y, label = plot, vp.width = 0.8, vp.height = 0.8))
Gives:
Here is a solution based on Z. Lin's answer, but using ggforce::facet_wrap_paginate() to do the filtering and keeping colourscales consistent.
First, we can make the 'root' plot containing all the data with no facetting.
library(ggpmisc)
library(tibble)
library(dplyr)
n_replicates <- c(rep(1:10,15),rep(seq(10,100,10),15),rep(seq(100,1000,100),15),rep(seq(1000,10000,1000),15))
sim_years <- rep(sort(rep((1:15),10)),4)
sd_data <- rep (NA,600)
for (i in 1:600) {
sd_data[i]<-rnorm(1,mean=exp(0.1 * sim_years[i]), sd= 1/n_replicates[i])
}
max_rep <- sort(rep(c(10,100,1000,10000),150))
data_frame <- cbind.data.frame(n_replicates,sim_years,sd_data,max_rep)
my_breaks = c(2, 10, 100, 1000, 10000)
facet_names <- c(
`10` = "2, 3, ..., 10 replicates",
`100` = "10, 20, ..., 100 replicates",
`1000` = "100, 200, ..., 1000 replicates",
`10000` = "1000, 2000, ..., 10000 replicates"
)
base <- ggplot(data=data_frame,
aes(x=sim_years,y=sd_data,group =n_replicates, col=n_replicates)) +
geom_line() +
theme_bw() +
scale_colour_gradientn(
name = "number of replicates",
trans = "log10", breaks = my_breaks,
labels = my_breaks, colours = rainbow(20)
) +
labs(title ="", x = "year", y = "sd")
Next, the main plot will be just the root plot with facet_wrap().
main <- base + facet_wrap(~ max_rep, ncol = 2, labeller = as_labeller(facet_names))
Then the new part is to use facet_wrap_paginate with nrow = 1 and ncol = 1 for every max_rep, which we'll use as insets. The nice thing is that this does the filtering and it keeps colour scales consistent with the root plot.
nmax_rep <- length(unique(data_frame$max_rep))
insets <- lapply(seq_len(nmax_rep), function(i) {
base + ggforce::facet_wrap_paginate(~ max_rep, nrow = 1, ncol = 1, page = i) +
coord_cartesian(xlim = c(12, 14), ylim = c(3, 4)) +
guides(colour = "none", x = "none", y = "none") +
theme(strip.background = element_blank(),
strip.text = element_blank(),
axis.title = element_blank(),
plot.background = element_blank())
})
insets <- tibble(x = rep(0.01, nmax_rep),
y = rep(10.01, nmax_rep),
plot = insets,
max_rep = unique(data_frame$max_rep))
main +
geom_plot_npc(data = insets,
aes(npcx = x, npcy = y, label = plot,
vp.width = 0.3, vp.height = 0.6)) +
annotate(geom = "rect",
xmin = 12, xmax = 14, ymin = 3, ymax = 4,
linetype = "dotted", fill = NA, colour = "black")
Created on 2020-12-15 by the reprex package (v0.3.0)

How do I graph on custom plots in ggplot2? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am using a plot obtained from the following site:
https://github.com/statsbylopez/blogposts/blob/master/fball_field.R
I do not know how to plot points on this. How would I go about doing this?
«...and thus haven't tried anything.» — Well, then just do that: try! You cannot fail!
base.football +
geom_point(aes(1:10, seq(1, 100, 10)), color = "red") +
geom_point(aes(0, 50), color = "blue")
Data
library(ggplot2)
theme.football <- function(){
theme(panel.grid.minor = element_blank(),
axis.text.y = element_text(angle=270, hjust=0.5),
panel.border = element_blank(),
panel.grid.major = element_line(size = 0.5, linetype = 'solid',
colour = "black"),
axis.ticks = element_blank())
}
xlim <- (160/3)/2
hash.width <- 3.3
hash.x <- (xlim + hash.width)/2
df.hash <- expand.grid(x = c(-1*xlim, -1*hash.width, hash.width, xlim), y = (0:100))
df.hash <- df.hash %>% filter(!(floor(y %% 5) == 0))
base.football <- ggplot() + xlab("") + ylab("") +
theme_minimal() +
annotate("segment", x = c(-1*xlim, -1*xlim, xlim, xlim),
y = c(-10, 110, 110, -10),
xend = c(-1*xlim, xlim, xlim, -1*xlim),
yend = c(110, 110, -10, -10), colour = "black") +
#geom_point(data = df.hash, aes(x, y), pch = 1) +
annotate("text", x = df.hash$x[df.hash$x < 0], y = df.hash$y[df.hash$x < 0], label = "_", hjust = 0, vjust = -0.2) +
annotate("text", x = df.hash$x[df.hash$x > 0], y = df.hash$y[df.hash$x > 0], label = "_", hjust = 1, vjust = -0.2) +
annotate("segment", x = rep(-1*xlim, 21),
y = seq(0, 100, by = 5),
xend = rep(xlim, 21),
yend = seq(0, 100, by = 5)) +
annotate("text", x = rep(-1*hash.x, 11), y = seq(0, 100, by = 10),
label = c("G ", seq(10, 50, by = 10), rev(seq(10, 40, by = 10)), " G"),
angle = 270, size = 4) +
annotate("text", x = rep(hash.x, 11), y = seq(0, 100, by = 10),
label = c(" G", seq(10, 50, by = 10), rev(seq(10, 40, by = 10)), "G "),
angle = 90, size = 4) +
scale_y_continuous("", breaks = NULL, lim = c(-10, 110)) +
scale_x_continuous("", breaks = NULL, lim = c(-1*xlim, xlim)) +
annotate("rect", xmin=-1*xlim, xmax=xlim, ymin=-10, ymax=110, fill="palegreen", alpha=0.1) +
theme.football()

ggtitle not displaying with ggmap

I do not understand why ggtitle("My Title") + or labs(title = "My Title") + is not displaying my title. Here is my code:
require(raster)
country <- getData("GADM", country="Australia",level = 0)
points <- data.frame(id = c(1:5), lon = c(125, 144, 150, 115, 139), lat = c(-20, -15, -34, -25, -21))
edges <- data.frame(from.lon = c(144, 139, 125), from.lat = c(-15,-21, -20), to.lon = c(150, 125, 144), to.lat = c(-34, -20, -15), resource_id = c(1:3))
centrepoint <- as.numeric(geocode("Australia"))
p1 <- ggmap(get_googlemap(center = centrepoint, scale = 2, zoom = 4, maptype = "satellite"), extent = "device") +
geom_polygon(data = country, aes( x = long, y = lat, group = group), fill = NA, color = "white", size = 0.25) +
geom_segment(data = filter(edges, edgelist$resource_id == 2),
size = 0.5,
color = "pink",
aes(y = from.lat, x = from.lon, yend = to.lat, xend = to.lon),
arrow = arrow(length = unit(0.25, "cm"), type = "closed")) +
coord_fixed(1.3) +
geom_point(aes(x = lon, y = lat), data = points, col = "pink", alpha = 0.5, size = 1.0) +
ggtitle("Money") +
theme(plot.margin = unit(c(1,1,1,1), "cm"))
p1
I am still learning ggplot.
It is a bit difficult to answer this question without at least minimal reproducible data. Without that information, it seems as though there is a problem with one of your geom calls (my guess is geom_polygon()) or associated data since this works fine:
library(ggplot2)
library(ggmap)
ggmap(
get_googlemap(
scale = 2,
zoom = 7,
maptype = "satellite"
),
extent = "device") +
coord_fixed(1) +
labs(title = "Money") +
# ggtitle("Money)
theme(plot.margin = unit(c(1,1,1,1), "cm"))

Custom axis break intervals

I have data with continuous x and y values. Over a specific x interval, I want to make the ticks increments to be smaller, e.g. from 50 to 60, the distance between the breaks should be 1 (50, 51, 52, 53 ... 59, 60). For the rest of the axis, it is fine to have the ticks incremented by 10. My desired x-axis would have breaks at:
10,20,30,40,50,51,52,53,54,55,56,57,58,58,60,70,80,90,..190,200
What I have tried:
x <- seq(1:200)
y <- seq(51, 250, by = 1)
df <- data.frame(x = x, y = y)
ggplot(data = df, aes(x, y)) +
geom_line(size=1.6)+
scale_x_continuous(breaks = c(10, 20, 30, 40, seq(50, 60, by = 2), seq(70, 200, 10)),
minor_breaks = seq(50, 60, by = 2)) +
theme(axis.text.x = element_text(size = 16),
axis.text.y = element_text(size = 16),
axis.title.x = element_text(size = 16),
axis.title.y = element_text(size = 16),
axis.ticks.x = element_line(size = 1),
axis.ticks.length = unit(0.8, "cm")) +
xlab("Time") + ylab("value")+
As you see, the labels are overlapping. How can I achieve this in a clearer way?
It seems very tight to squeeze in more labels than every 10. So you may try to drop the labels at tickmark 52 to 58, by labelling these four positions with ""
ggplot(data = df, aes(x = x, y = y)) +
geom_line() +
scale_x_continuous(breaks = c(seq(from = 10, to = 200, by = 10),
seq(from = 52, to = 58, by = 2)),
labels = c(seq(from = 10, to = 200, by = 10), rep("", 4)))
Alternatively, you can zoom in on the relevant x-range using coord_cartesian. The underlying data is unchanged, and we just magnify a small section of the original data. The zoomed-in plot can then be added to the original plot as a subplot. There are many ways to arrange subplots. Here is one example:
# The original plot on full range of x
g1 <- ggplot(data = df, aes(x = x, y = y)) +
geom_line()
# zoom in to the relevant section of x
g2 <- ggplot(data = df, aes(x = x, y = y)) +
geom_line() +
coord_cartesian(xlim = c(49, 61)) +
scale_x_continuous(breaks = seq(from = 50, to = 60, by = 2))
# print g1, and then add g2 on top using viewport from package grid
g1
print(g2, vp = viewport(x = 0.75, y = 0.3, width = 0.35, height = 0.35))

Resources