Related
I have made a graph from 2 different tables, red is users and blue is non users. How can I create a legend.
structure(list(Attribute = c("Nscore", "Escore", "Oscore", "Ascore",
"Cscore", "Impulsivity", "SS"), Mean = c(0.519519745762712, -0.224147033898305,
0.345051694915254, -0.542761016949153, -0.432290169491526, 0.573723898305084,
0.625454406779661), lower_bound = c(0.345515567755788, -0.421929253136834,
0.173007836159723, -0.743825778750619, -0.620318735695037, 0.417301607369938,
0.461852381381636), upper_bound = c(0.693523923769636, -0.0263648146597761,
0.517095553670785, -0.341696255147686, -0.244261603288014, 0.730146189240231,
0.789056432177685)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-7L))
structure(list(Attribute = c("Nscore", "Escore", "Oscore", "Ascore",
"Cscore", "Impulsivity", "SS"), Mean = c(-0.0346437351443125,
0.014794833050368, -0.0236125863044712, 0.0359841765704582, 0.0284564233163561,
-0.0306152461799648, -0.0452792359932086), lower_bound = c(-0.0809079532901976,
-0.0313902162687121, -0.0700665170072849, -0.00972637107557454,
-0.0176800056429342, -0.0748829267378616, -0.089769617527101),
upper_bound = c(0.0116204830015727, 0.0609798823694481, 0.0228413443983426,
0.0816947242164909, 0.0745928522756465, 0.0136524343779321,
-0.000788854459316299)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -7L))
ggplot(UserCI, aes(Attribute, Mean)) +
geom_point() + geom_errorbar(aes(ymin = lower_bound, ymax = upper_bound), colour="red") +
geom_point(data = NonUserCI, aes(Attribute, Mean)) +
geom_errorbar(aes(ymin =NonUserCI$lower_bound, ymax = NonUserCI$upper_bound), colour = "blue")
If you want to get a legend then map on aesthetics, i.e. map on the color aes inside aes() and set your desired colors via scale_color_manual:
library(ggplot2)
ggplot(UserCI, aes(Attribute, Mean)) +
geom_point() +
geom_errorbar(aes(ymin = lower_bound, ymax = upper_bound, color = "user")) +
geom_point(data = NonUserCI, aes(Attribute, Mean)) +
geom_errorbar(data = NonUserCI, aes(ymin = lower_bound, ymax = upper_bound, color = "nonuser")) +
scale_color_manual(
values = c("user" = "red", "nonuser" = "blue"),
labels = c("user" = "User", "nonuser" = "Non-User")
)
I have a plot that looks at 2 quarts worth of data. I also included a target value (dashed line) and a YTD section (which is the cumsum(count).
I am having an issue trying to show the # in that section added for YTD but only for 1 of the quarters (since Q1 should already have a value inside the bar plot). Currently it is showing 0 and 2 in the plot below but I only want to show everything > Q1 values.
Current plot
I have tried with this current approach but does not seem to work:
**geom_text(aes(label = ifelse((quarter_2022= "Q1"), total_attainment, ifelse(quarter_2022="Q2",total_attainment+2)),
position = position_stack(vjust = 1))) +**
Plot Code
ggplot(df1, aes(x=quarter_2022, y=total_attainment)) +
geom_col(aes(y = YTD_TOTAL), fill = c("green1", "green2"), color = "black") +
geom_text(aes(y = YTD_TOTAL, label = scales::percent(YTD_PERCENT_ATTAINMENT)),
vjust = -0.5) +
geom_col(fill = "gray70", color = "gray20") +
geom_text(aes(label = YTD_TOTAL - total_attainment),
position = position_stack(vjust = 1.25))+
geom_text(aes(label = total_attainment),
position = position_stack(vjust = 0.5))+
geom_segment(aes(x = as.numeric(as.factor(quarter_2022)) - 0.4,
xend = as.numeric(as.factor(quarter_2022)) + 0.4,
y = attainment_target, yend = attainment_target),
linetype = "dashed") +
geom_text(aes(label = attainment_target),
position = position_stack(vjust = 4))
Here is the data:
structure(list(attainment_target = c(7.5, 15), quarter_2022 = c("Q1",
"Q2"), year = structure(c(1640995200, 1640995200), class = c("POSIXct",
"POSIXt"), tzone = ""), total_attainment = c(2, 4), percent_attainment_by_quarter = c(0.2666,
0.2666), ytd = c(2, 6), YTD_TOTAL = c(2, 6), YTD_PERCENT_ATTAINMENT = c(0.266666666666667,
0.4)), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame"
))
Create a logical column in your dataset that indicates whether the label is 0. In the geom_text that creates the label, set the color aesthetic to the logical column. Use scale_color_manual(values = c(NA, "black"), na.value = NA) to assign no color to the labels that were 0s.
Given this simple data I want to plot the equivalent of base
plot(dat$value)
but with ggplot.
dat= structure(list(name = c("Cord", "Cord",
"amo", "amo",
"amo", "ramo"),
value = c(7, 0.7, 9,
0.9, 0.8, 0.7)), row.names = c(NA,
6L), class = "data.frame")
I tried:
> ggplot(data = dat) + geom_point(aes(x = value, colour = name))
Error in `check_required_aesthetics()`:
! geom_point requires the following missing aesthetics: y
I need to plot "count" on y axis vs value on x axis
You could create a row index using tibble::rownames_to_column, then use that to plot along the x-axis, so that you get a similar result to plot(dat$value).
library(tidyverse)
dat %>%
rownames_to_column("ind") %>%
ggplot(aes(x = ind, y = value, color = name)) +
geom_point(size = 3) +
theme_bw()
Output
Or you can put the function directly into ggplot:
ggplot(dat, aes(
x = rownames_to_column(dat)$rowname,
y = value,
color = name
)) +
geom_point(size = 3) +
theme_bw()
Or another option is to use row.names:
ggplot(dat, aes(x = as.numeric(row.names(dat)), y = value, colour = name)) +
geom_point()
Base R plot(dat$value) has an implicit x equal to seq_along(dat$value).
Use x = seq_along(value) and y = value.
dat <- structure(list(name = c("Cord", "Cord",
"amo", "amo",
"amo", "ramo"),
value = c(7, 0.7, 9,
0.9, 0.8, 0.7)),
row.names = c(NA, 6L),
class = "data.frame")
library(ggplot2)
ggplot(dat, aes(x = seq_along(value), y = value, color = name)) +
geom_point()
Created on 2022-03-01 by the reprex package (v2.0.1)
I have the following dataset
structure(list(X = c(9.8186734, 19.6373468, 29.4560202, 39.2746936,
49.093367, 58.9120404, 68.7307138, 78.5493872, 88.3680606, 98.186734
), Y = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), radii = c(530.595715856625,
530.595715856625, 524.270569515141, 520.785212389348, 524.423046929159,
524.777454042683, 523.089321742221, 522.852371975715, 523.124870390148,
522.612174462367), slope = c(-21.796356958782, -21.796356958782,
-21.796356958782, -21.796356958782, -21.796356958782, -21.796356958782,
-21.796356958782, -21.796356958782, -21.796356958782, -21.796356958782
)), row.names = c(NA, -10L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: 0x7f989f011ce0>, sorted = "Y")
and I am simply trying to print slope as a text to the figure as
str_slope <- c(substitute("Slope = "~sp~mu*"m/s", list(sp = sprintf("%2.1f", dt[!duplicated(slope), slope]))))
d_text <- data.table(x=2000, y=500, label = str_slope)
ggplot(dt, aes(x = X, y=radii)) +
geom_point()+
geom_smooth(method = "lm", level = 0.9999, se = TRUE)+
scale_colour_manual(values = getPalette) +
labs(x = "time (s)", y = expression("radius ["*mu*"m]"), color = "Speed [µm/s]") +
geom_text(data = d_text, aes(x = x, y = y, label = label))+
theme_default(legend.position = "none")
but I get something like this
Why is the text in str_slope not evaluated as an expression? How can I force ggplot to interpret it as an expression, so that the text will look like
For this type of plot annotation, you should use annotate(geom="text"...) rather than geom_text(). For how to generate the expression, you can use the parse=TRUE argument within annotate().
I think we're missing all your plot data, so here's an example with mtcars that incorporates the contents of str_slope in your example.
str_slope <- c(substitute("Slope = "~sp~mu*"m/s", list(sp = sprintf("%2.1f", dt[!duplicated(slope), slope]))))
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
p + annotate(
"text", x=4, y=25,
label= str_slope, parse=TRUE)
For your information, geom_text() is designed to be used wherein one or more aesthetics are mapped to a data frame. If you have only one line of text you want to appear on the plot, you should use annotate(geom="text"...), which is used when you do not want to map any aesthetics to a data frame.
I have a stacked bar plot, with highly unequal heights of bars. I would like to show the percentages on top of each bar.
What I have done so far is the following
df = structure(list(Type = c("Bronchoscopy", "Bronchoscopy", "Endoscopy",
"Endoscopy"), Bacteremia = structure(c(1L, 2L, 1L, 2L), .Label = c("False",
"True"), class = "factor"), count = c(2710L, 64L, 13065L, 103L
), perc = c(97.6928622927181, 2.3071377072819, 99.2178007290401,
0.782199270959903)), class = c("grouped_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -4L), groups = structure(list(
Type = c("Bronchoscopy", "Endoscopy"), .rows = list(1:2,
3:4)), row.names = c(NA, -2L), class = c("tbl_df", "tbl",
"data.frame"), .drop = TRUE))
ggplot(df, aes(x = Type, y = perc, fill = Bacteremia)) +
geom_bar(stat = "identity") +
ylab("percent") +
geom_text(aes(label = paste0(round(perc, 2), "%")), position =
position_stack(vjust = -0.1), color = "black", fontface = "bold")
I can't seem to get the vjust right. It seems like it's not behaving in the same way for the bottom versus the top bar.
What I would like to achieve is to place the percentages slightly higher than the top edge of each bar.
Any ideas?
Here's a possible approach:
ggplot(df, aes(x = Type, y = perc, fill = Bacteremia)) +
geom_bar(stat = "identity") +
ylab("percent") +
geom_text(aes(label = paste0("", round(perc, 2), "%\n"), y = perc),
color = "black", fontface = "bold", nudge_y = 2)
I should elaborate that ggplot2 is going to try to place the geom_text() relative to the data. If you are trying to align horizontally the text labels, you will need to either use annotate() or supply a labelling dataset with type, percent and Bacteremia and call that in geom_text() as below.
labdf <- cbind(df, ypos = c(103, 5, 103, 5))
ggplot(df, aes(x = Type, y = perc, fill = Bacteremia)) +
geom_bar(stat = "identity") +
ylab("percent") +
geom_text(data = labdf,
aes(label = paste0("", round(perc, 2), "%"), y = ypos, x = Type),
color = "black", fontface = "bold")
Here's one way to do it:
df <-
tibble(
Type = c("Bronchoscopy", "Bronchoscopy", "Endoscopy", "Endoscopy"),
Bacteremia = c("False", "True", "False", "True"),
count = c(2710L, 64L, 13065L, 103L)
) %>%
group_by(Type) %>%
mutate(Percent = round((count / sum(count) * 100), 1))
df %>%
ggplot(aes(x = Type, y = Percent, fill = Bacteremia)) +
geom_col() +
geom_label(
data = . %>% filter(Bacteremia == "True"),
aes(y = Percent + 5, label = str_c(Percent, "%")),
show.legend = FALSE
) +
geom_label(
data = . %>% filter(Bacteremia == "False"),
aes(y = 105, label = str_c(Percent, "%")),
show.legend = FALSE
)
The choices of 5 and 105 work on my computer, but may need to be tweaked a bit based on your specific settings and aspect ratio. The first geom_label call sets the y-axis based on the precise percentage, while the second one sets it at a constant level above the bars.
You might also want to play around with using geom_text vs. geom_label to experiment with different color and label settings. The nice thing about geom_label is that it will make it very clear which group is being labeled.