Bubble chart without axis with labels in R - r

I have the following data frame:
> dput(df)
structure(list(text = structure(c(9L, 10L, 1L, 7L, 5L, 12L, 1L,
11L, 5L, 8L, 2L, 13L, 2L, 5L, NA, 6L, 13L, 4L, NA, 5L, 4L, 3L
), .Label = c("add ", "change ", "clarify", "correct", "correct ",
"delete", "embed", "follow", "name ", "remove", "remove ", "specifiy ",
"update"), class = "factor"), ID = c(1052330L, 915045L, 931207L,
572099L, 926845L, 510057L, 927946L, 490640L, 928498L, 893872L,
956074L, 627059L, 508649L, 508657L, 1009304L, 493138L, 955579L,
144052L, 1011166L, 151059L, 930992L, 913074L)), .Names = c("text",
"ID"), class = "data.frame", row.names = c(NA, -22L))
I would like to have a bubble chart for my df with circles labeling with each verb in the text column and also the number of IDs that are related to each verb in the text column. This is the code I have for the circles but I don't know how to do the labeling:
> library(packcircles)
> library(ggplot2)
> packing <- circleProgressiveLayout(df)
> dat.gg <- circleLayoutVertices(packing)
> ggplot(data = dat.gg) +geom_polygon(aes(x, y, group = id, fill = factor(id)), colour = "black",show.legend = FALSE) +scale_y_reverse() +coord_equal()

You create a data.frame for your labels with the appropriate x and y coordinate and use geom_text
library(ggplot2)
packing <- circleProgressiveLayout(df)
dat.gg <- circleLayoutVertices(packing)
cbind(df, packing) -> new_df
ggplot(data = dat.gg) +geom_polygon(aes(x, y, group = id, fill = factor(id)), colour = "black",show.legend = FALSE) +
scale_y_reverse() +coord_equal() +geom_text(data = new_df, aes(x, y,label = text))
For the Text and ID, you can do:
new_df$text2 <- paste0(new_df$text,"\n",new_df$ID)
ggplot(data = dat.gg) +geom_polygon(aes(x, y, group = id, fill = factor(id)), colour = "black",show.legend = FALSE) +
scale_y_reverse() +coord_equal() +geom_text(data = new_df, aes(x, y,label = text2))

Related

Where to properly position ggplotly tooltip in ggplot?

When I add a text line to a geom_line plot, the line disappears.
library(tidyverse)
library("lubridate")
library(plotly)
library("RColorBrewer")
library(htmlwidgets)
library("reprex")
activity <- c("N", "FB", "N", "N", "N", "FA", "N", "FA", "N", "FA", "N", "N", "N", "N", "N", "FA", "N", "N", "N", "N", "FA", "N", "N", "FA", "FA")
activity_date <- as.Date(c(NA, "2022-04-19", "2022-05-01", "2022-05-01", "2022-05-06", "2022-05-06", "2022-05-07", "2022-05-07", "2022-05-09", "2022-05-09", "2022-05-10", "2022-05-13", "2022-05-14", "2022-05-14", "2022-05-14", "2022-05-15", "2022-05-15", "2022-05-15", "2022-05-15", "2022-05-15", "2022-05-16", "2022-05-16", "2022-05-16", "2022-05-16", "2022-05-16"))
fcrawl_cum <- c(0L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 8L)
clutch_cum <- c(1L, 1L, 2L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 8L, 9L, 10L, 11L, 11L, 12L, 13L, 14L, 15L, 15L, 16L, 17L, 17L, 17L)
turtle_activity_gtm <- tibble(activity, activity_date, fcrawl_cum, clutch_cum)
the_pal <- RColorBrewer::brewer.pal(n = 8,"Dark2") #Set color palette.
myplot2 <-
ggplot() +
geom_line(data = turtle_activity_gtm,
aes(x=activity_date, y=fcrawl_cum,
text = paste("Date: ", as.Date(activity_date),
"<br>Total: ", fcrawl_cum)),
na.rm = TRUE,
linetype = "111111",
linewidth = 1.5, color = the_pal[6]) +
geom_line(data = turtle_activity_gtm,
aes(x=activity_date, y=clutch_cum),
na.rm = TRUE,
linewidth = 1.5,
color = the_pal[7]) +
labs(title = "myplot2")
myplot2
ggplotly(myplot2)
ggplotly(myplot2, tooltip = c("text"))
If I use, ggplotly(myplot2) the line with the text line added is still not there. However, the data points still appear for missing line. If I use ggplotly with the added tooltip, ggplotly(myplot2, tooltip = c("text")) ,the label is missing for the line without the added text line but the label is exactly as written in the text line.
I would show some of the plots; however, I am not allow to yet. Reputation too low.
How can I do this properly so that both lines show with the added tooltip? I eventually want both lines to have their own text lines added. This is a very simplified chart. One I can get past this problem, I plan to eventually add a lot more items to this chart with a full data set.
Thanks,
Jeff
When adding the text attribute to geom_line you have to explicitly set the group aesthetic, i.e. use e.g. group=1 to tell ggplot2 that all observations belong to one group which for simplicity I called 1:
library(tidyverse)
library(plotly)
myplot2 <-
ggplot() +
geom_line(
data = turtle_activity_gtm,
aes(
x = activity_date, y = fcrawl_cum, group = 1,
text = paste(
"Date: ", as.Date(activity_date),
"<br>Total: ", fcrawl_cum
)
),
na.rm = TRUE,
linetype = "111111",
linewidth = 1.5, color = the_pal[6]
) +
geom_line(
data = turtle_activity_gtm,
aes(x = activity_date, y = clutch_cum),
na.rm = TRUE,
linewidth = 1.5,
color = the_pal[7]
) +
labs(title = "myplot2")
#> Warning in geom_line(data = turtle_activity_gtm, aes(x = activity_date, :
#> Ignoring unknown aesthetics: text
ggplotly(myplot2, tooltip = c("text"))
EDIT TBMK there is only one text attribute, i.e. specify your tooltip via text the same way as for the first geom_line and use tooltip=c("text").
But a more ggplot2 like approach to create your chart would be to first reshape your data to long format. Doing so allows to create your plot with just one geom_line but requires map on the color aes, to map on the group aes appropriately and to set your colors via scale_color_manual. Note that doing so will automatically add a legend to your plot:
turtle_activity_gtm_long <- turtle_activity_gtm %>%
tidyr::pivot_longer(c(fcrawl_cum, clutch_cum))
ggplot() +
geom_line(
data = turtle_activity_gtm_long,
aes(
x = activity_date, y = value,
color = name, group = name,
text = paste(
"Date: ", as.Date(activity_date),
"<br>Total: ", value
)
),
na.rm = TRUE,
linewidth = 1.5
) +
scale_color_manual(values = c(clutch_cum = the_pal[[7]], fcrawl_cum = the_pal[[6]])) +
labs(title = "myplot2")
ggplotly(tooltip = c("text"))

Removing "False"-condition scales::dollar labels on ifelse within geom_label

trying to establish individual bar data labels ONLY if the value is negative. I was able to do it fine for a variable that comprised simple integers, but for a variable that needs to be formatted as dollar with the thousands separator, I can't seem to get rid of the "NA" label.
DolSumPlot <- ggplot(data = DolSums, aes(x = Group.1, fill = Group.2)) +
geom_bar(aes(weight = x), position = position_stack(reverse = TRUE)) +
coord_flip() +
labs(title = "Dollars Billed by Technician and Shop, Between 02/01/2018 and 05/31/2018",
y = "Dollars Billed", x = "Technician", fill = "Shop") +
scale_y_continuous(limits= c(NA,NA),
labels = scales::dollar,
breaks = seq(0, 50000 + 10000, 5000*2),
minor_breaks = seq(0,50000 + 10000, by = 5000)) +
scale_fill_brewer(palette = "Set1") +
geom_label(aes(label=scales::dollar(ifelse(DolSums$x < 0, DolSums$x,NA)),
y = DolSums$x),
show.legend = FALSE, size = 2.6, colour = "white", fontface = "bold")
Data:
DolSums = structure(list(Group.1 = c((names)), Group.2 = structure(c(4L, 4L, 4L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 3L, 3L, 3L, 6L, 6L, 6L, 6L, 6L, 6L, 6L,
5L, 5L, 5L, 5L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Radio",
"Video", "Engineering", "800Mhz", "PSSRP", "Other"), class = "factor"),
x = c(4646, 16008.5, 48793.1, 4040, 14468.25, 13332, 1565.5,
6060, 6549.85, 2929, 4444, 3257.25, 5904, 2029.5, 3321, 6767,
8105.25, 8105.25, 8130.5, 3131, 5075.25, 3383.5, 4418.75,
23381.5, 1363.5, -2323, 29133.45, 2550.25, 505, 26042.85,
35203.55, 35940.85, 1641.25, 45066.2, 37541.7, 606, 45439.9
)), .Names = c("Group.1", "Group.2", "x"), row.names = c(NA,
-37L), class = "data.frame")
You can do this by using the data argument in geom_label and subsetting only rows with negative x. Also note that since you already have DolSums as input, there is no need to write DolSums$x. Instead, use column name to refer to a specific column directly:
library(ggplot2)
ggplot(data = DolSums, aes(x = Group.1, fill = Group.2)) +
geom_bar(aes(weight = x), position = position_stack(reverse = TRUE)) +
coord_flip() +
labs(title = "Dollars Billed by Technician and Shop, Between 02/01/2018 and 05/31/2018",
y = "Dollars Billed", x = "Technician", fill = "Shop") +
scale_y_continuous(limits= c(NA,NA),
labels = scales::dollar,
breaks = seq(0, 50000 + 10000, 5000*2),
minor_breaks = seq(0,50000 + 10000, by = 5000)) +
scale_fill_brewer(palette = "Set1") +
geom_label(data = DolSums[DolSums$x < 0,],
aes(label=scales::dollar(x),
y = x),
show.legend = FALSE, size = 2.6, colour = "white", fontface = "bold")

Annotate faceted plot in ggplot2

I am working on the dataset reported here below (pre.sss)
pre.sss <- pre.sss <- structure(list(Pretest.num = c(63, 62, 61, 60, 59, 58, 57, 4,2, 1), stress = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L,1L), .Label = c("[0,6]", "(6,9]"), class = "factor"), time = c(1L,1L, 1L, 1L, 1L, 1L, 1L, 8L, 8L, 8L), after = structure(c(2L,2L, 2L, 2L, 2L, 2L, 1L, 1L, NA, 1L), .Label = c("no", "yes"), class = "factor"),id = c("call_fam", "call_fam", "call_fam", "call_fam", "call_fam","call_fam", "call_fam", "counselor", "counselor", "counselor")), .Names = c("Pretest.num", "stress", "time", "after","id"), reshapeLong = structure(list(varying = structure(list(after = c("after.call.fam", "after.speak", "after.send.email","after.send.card", "after.attend", "after.fam.mtg", "after.sup.grp","after.counselor")), .Names = "after", v.names = "after", times = 1:8),v.names = "after", idvar = "Pretest.num", timevar = "time"), .Names = c("varying","v.names", "idvar", "timevar")), row.names = c("63.1", "62.1","61.1", "60.1", "59.1", "58.1", "57.1", "4.8", "2.8", "1.8"), class = "data.frame")
and I need to plot the counts of several categorical variables according to a specific level of another categorical variable ('stress'): so, a faceted bobble-lot would do the job in my case
So what I do is the following:
ylabels = c('call_fam' = "call fam.member for condolences",
'speak' = "speak to fam.member in person",
'send.email' = "send condolence email to fam.member",
'send.card' = "send condolence card/letter to fam.member",
'attend' = "attend funeral/wake",
'fam.mtg' = "provide fam.meeting",
'sup.grp' = "suggest attending support grp.",
'counselor' = "make referral to bereavement counselor" )
p = ggplot(pre.sss, aes(x = after, y = id)) +
geom_count(alpha = 0.5, col = 'darkblue') +
scale_size(range = c(1,30)) +
theme(legend.position = 'none') +
xlab("Response") +
ylab("What did you do after learning about death?") +
scale_y_discrete(labels = ylabels) +
facet_grid(.~ pre.sss$stress, labeller = as_labeller(stress.labels))
and I obtain the following image, exactly as I want.
Now I would like to label each bubble with the count with which the corresponding data appear in the dataset.
dat = data.frame(ggplot_build(p)$data[[1]][, c('x', 'y', 'PANEL', 'n')])
dat$PANEL = ifelse(dat$PANEL==1, "[0,6]", "(6-9]")
colnames(dat) = c('x', 'y', 'stress', 'n')
p + geom_text(aes(x, y, label = n, group = NULL), data = dat)
This gives me the following error I really can't understand.
> p + geom_text(aes(x, y, label=n, group=NULL), data=dat)
Error in `$<-.data.frame`(`*tmp*`, "PANEL", value = c(1L, 1L, 1L, 1L, :
replacement has 504 rows, data has 46
Can anybody help me with this?
Thanks!
EM
The function you refer to as your labeller function is missing from this example still. geom_count uses stat_sum, which calculates a parameter n, the number of observations at that point. Because you can use this calculated parameter, you don't actually have to assign the plot to a variable and pull out its data, as you did with ggplot_build.
This should do what you're looking for:
ggplot(pre.sss, aes(x = after, y = id)) +
geom_count(alpha = 0.5, col = 'darkblue') +
# note the following line
stat_sum(mapping = aes(label = ..n..), geom = "text") +
scale_size(range = c(1,30)) +
theme(legend.position = 'none') +
xlab("Response") +
ylab("What did you do after learning about death?") +
scale_y_discrete(labels = ylabels) +
facet_grid(.~ stress)
The line I added computes the same thing as what's behind the scenes in geom_count, but gives it a text geom instead, with the label mapped to that computed parameter n.

Draw radial background in ggplot

this is my dataset:
> dput(dfw)
structure(list(SITE = c("ASPEN", "ASPEN", "BioCON", "DUKE", "Lancaster",
"Merrit Island", "Nevada FACE", "NZ", "ORNL", "PHACE", "BioCON"
), SPECIES = c("A", "AB", "Legume", "PITA", "mixed", "Oak", "desert",
"grassland", "SG", "grassland", "C3forb"), FRr = c(0.197028535345918,
0.296799297050907, 0.195436310641759, 0.152972526753089, 0.0313948973476966,
0.139533057346518, 0.188221278921143, NA, 0.70542764380006, 0.119320766735777,
0.135665667633474), Nupr = c(0.122177669046786, 0.305573297532757,
0.131181914007488, 0.217519050530067, -0.0436788294371676, 0.153632658941404,
-0.00803217169726427, 0.168440046857285, 0.145172439177718, -0.108563178158001,
0.00546006390438276), myc = c("ECM", "ECM", "N-fixing", "ECM",
"ECM", "ECM", "AM", "AM", "AM", "AM", "AM"), SITE_Sps = structure(c(1L,
2L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 3L), .Label = c("Aspen FACE-A",
"Aspen FACE-AB", "BioCON", "BioCON-legumes", "Duke FACE", "Lascaster",
"Florida OTC", "Nevada FACE", "NZ FACE", "ORNL FACE", "PHACE"
), class = "factor")), row.names = c(NA, -11L), vars = list(SITE,
SPECIES, myc), indices = list(0L, 1L, 10L, 2L, 3L, 4L, 5L,
6L, 7L, 8L, 9L), group_sizes = c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L), biggest_group_size = 1L, labels = structure(list(
SITE = c("ASPEN", "ASPEN", "BioCON", "BioCON", "DUKE", "Lancaster",
"Merrit Island", "Nevada FACE", "NZ", "ORNL", "PHACE"), SPECIES = c("A",
"AB", "C3forb", "Legume", "PITA", "mixed", "Oak", "desert",
"grassland", "SG", "grassland"), myc = structure(c(2L, 2L,
1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("am", "ecm",
"ecm+am"), class = "factor")), row.names = c(NA, -11L), class = "data.frame", vars = list(
SITE, SPECIES, myc), .Names = c("SITE", "SPECIES", "myc")), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), .Names = c("SITE", "SPECIES",
"FRr", "Nupr", "myc", "SITE_Sps"))
I want to draw the same background as in the attached figure, added to my current ggplot code:
ggplot(dfw, aes(FRr, Nupr, group=myc, label = SITE_Sps)) +
geom_point(aes(fill=myc),size=4,shape = 21) +
geom_text() +
geom_hline(yintercept=0) + geom_vline(xintercept = 0) +
geom_abline(intercept = 0, slope = 1, linetype = "longdash")
I guess I should use the function geom_polygon, but I don't really know how to create a dataset to draw all the required segments, including the colour gradient from dark grey to light grey and white.
Perhaps this could be a start?
nlines <-
phis <- seq( 0, 2*pi, by=2*pi/nlines )
rad <- 999
xs <- rad * cos( phis )
ys <- rad * sin( phis )
Here is a way using geom_polygon:
nlines <- 25
inc <- pi/(nlines)
phis <- seq( -pi/2, by=inc, length.out = nlines )
rad <- 1
#Create the triangles
points <- lapply(phis, function(a) {
x <-c(0, rad*cos(a), rad*cos(a+inc),0, -rad*cos(a), -rad*cos(a+inc))
y <-c(0, rad*sin(a), rad*sin(a+inc),0, rad*sin(a), rad*sin(a+inc))
g <-c(a,a,a,a,a,a) # used for grouping
data.frame(x,y,g)
})
#Create a data.frame to be used on ggplot
bckg <- do.call(rbind,points)
#You need to set the data for each geometry as we have more than one dataset
ggplot(mapping=aes(FRr, Nupr, group=myc)) +
#Draw the background
geom_polygon(data=bckg,aes(x=x,y=y,group=g,alpha=g), fill = "gray50")+
geom_point(data=dfw, aes(FRr, Nupr, group=myc, fill=myc),size=4,shape = 21) +
geom_text(data=dfw, aes(FRr, Nupr, group=myc, label = SITE_Sps), nudge_y = -0.02) +
geom_hline(data=dfw,yintercept=0) + geom_vline(data=dfw,xintercept = 0) +
geom_abline(data=dfw,intercept = 0, slope = 1, linetype = "longdash")+
#We need to define a scale in ourder to deal with out of boundary points on the background
scale_x_continuous(limits = c(-0.2,0.4), oob=function(x, rg) x)+
scale_y_continuous(limits = c(-0.2,0.4), oob=function(x, rg) x)+
scale_alpha_continuous(guide="none", range=c(1.0,0))+
theme(panel.background = element_blank())
Here is the plot:

ggplot2 barplot

I have small data.frame which I managed to plot in ggpot. Since ggplot does not support patterns , I graph the data with colors. I would appreciate a better presentation than the one I did in terms of coloring and design or even black and white. Also, I couldn't change the legend title
My data:
structure(list(Type = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L,
9L, 8L), .Label = c("Type A+Mod ", "Type B+C+D", "Type E+A",
"Type G+W", "Type H & Mod C", "Type Operation", "Type Production",
"Type Sales", "X, T, S"), class = "factor"), X2011 = structure(c(7L,
4L, 6L, 5L, 9L, 8L, 3L, 1L, 2L), .Label = c("$1,517.00", "$1,579.00",
"$1,727.00", "$105,352.00", "$126,787.00", "$141,647.00", "$187,506.00",
"$24,968", "$30,397.00"), class = "factor"), X2012 = structure(c(7L,
6L, 5L, 4L, 8L, 9L, 3L, 2L, 1L), .Label = c("$1,232.00", "$1,406.00",
"$1,963.00", "$109,533.00", "$125,795.00", "$166,251.00", "$172,238.00",
"$18,040.00", "$23,541.00"), class = "factor"), X2013 = structure(c(8L,
4L, 3L, 2L, 7L, 6L, 5L, 1L, 9L), .Label = c("$1,324.00", "$102,216.00",
"$125,101.00", "$198,769.00", "$2,088.00", "$20,070.00", "$21,094.00",
"$243.91", "$997.00"), class = "factor")), .Names = c("Type",
"X2011", "X2012", "X2013"), class = "data.frame", row.names = c(NA,
-9L))
The code:
colnames(DF)<-c("Type","2011","2012","2013")
dfMelt<-melt(DF, id.var="Type")
graph<- ggplot(dfMelt,aes(x=Type, y=value))+
geom_bar(aes(fill=variable),stat="identity", position="dodge",linetype=1,colour="red")+
#Tried this for black and white-Seems not working
#scale_colour_grey(start = 0, end = .9) +
theme_bw()+
theme(panel.background = element_rect(fill="grey98"))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
theme(axis.title.x=element_text(size=14,face="bold",vjust=-0.2),
axis.title.y=element_text(size=14,face="bold",vjust=0.15))+
theme(axis.ticks.x = element_line(size = 2))+
scale_x_discrete(expand=c(0.01,0))+
scale_y_discrete(expand=c(0.004,0.5))
print(graph)
Your values are being treated as factors rather than numbers, so the chart doesn't make sense. So first you want to convert them to numeric values:
DF <- cbind(DF[1],sapply(DF[-1], function(x) as.numeric(gsub("[$,]","",x))))
Then you can proceed as before, but obviously changing the discrete scale expansion on the y axis to a continuous one which also formats the values as dollars and using the Blues Brewer palette with scale_fill_brewer which works well in black and white and in colour. You can set the legend title when setting the palette here too.
dfMelt<-melt(DF, id.var="Type")
graph<- ggplot(dfMelt,aes(x=Type, y=value))+
geom_bar(aes(fill=variable),stat="identity", position="dodge",linetype=1,colour="red")+
theme_bw()+
theme(panel.background = element_rect(fill="grey98"))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
theme(axis.title.x=element_text(size=14,face="bold",vjust=-0.2),
axis.title.y=element_text(size=14,face="bold",vjust=0.15))+
theme(axis.ticks.x = element_line(size = 2))+
scale_x_discrete(expand=c(0.01,0))+
scale_y_continuous("Price",labels=dollar)+
scale_fill_brewer("Year", palette="Blues")
Which gives:
First of all, your data is not in the correct format. Now it's a factor-variable and it needs to be numeric. Moreover remove the comma's (for the thousands) and the $ valuta-sign. I also cleaned up the ggplot code.
DF <- cbind(DF[1],sapply(DF[-1], function(x) as.numeric(gsub("[$,]","",x)))) # copied from James
colnames(DF)<-c("Type","2011","2012","2013")
dfMelt <- melt(DF, id.var="Type")
ggplot(dfMelt,aes(x=Type, y=value)) +
geom_bar(aes(fill=variable),stat="identity", position="dodge") +
theme_bw() +
theme(panel.background = element_rect(fill="grey98"),
axis.text.x = element_text(angle = 45, hjust = 1),
axis.title.x=element_text(size=14,face="bold",vjust=-0.2),
axis.title.y=element_text(size=14,face="bold",vjust=0.15),
axis.ticks.x = element_line(size = 2)) +
scale_y_continuous("Price (in dollars)") +
scale_fill_discrete("Year")
The result:

Resources