Using the following data:
Category <- c("Bankpass", "Bankpass", "Bankpass", "Moving", "Moving")
Subcategory <- c("Stolen", "Lost", "Login", "Address", "New contract")
Weight <- c(10,20,13,40,20)
Duration <- as.character(c(0.2,0.4,0.5,0.44,0.66))
Silence <- as.character(c(0.1,0.3,0.25,0.74,0.26))
df <- data.frame(Category, Subcategory, Weight, Duration, Silence)
Which I use to create the following mosaic plot:
library (ggplot2)
library (ggmosaic)
g <- ggplot(data = df) +
geom_mosaic(aes(weight = Weight, x = product(Category), fill = Duration),
offset = 0, na.rm = TRUE) +
theme(axis.text.x = element_text(angle = -25, hjust = .1)) +
theme(axis.title.x = element_blank()) +
scale_fill_manual(values = c("#e8f5e9", "#c8e6c9", "#a5d6a7", "#81c784", "#66bb6a"))
This works, however I would like to include text labels on the elements on the graph ("Showing fe stolen, lost" etc.)
However, when I do:
g + geom_text(x = Category, y = Subcategory, label = Weight)
I get the following error:
Error in UseMethod("rescale") : no applicable method for 'rescale' applied to an object of class "character"
Any thoughts on what goes wrong here?
Method 1: Using geom_text() This method is used to add Text labels to data points in ggplot2 plots.
To create a mosaic plot using base ggplot2, we would need to compute the respective x and y values for each rectangle. We represent states along the y-axis and Product Categories along the x-axis. We calculate the respective xmin, xmax, ymin and ymax of the by grouping by Product Categories and States.
Designed to create visualizations of categorical data, geom_mosaic() has the capability to produce bar charts, stacked bar charts, mosaic plots, and double decker plots and therefore offers a wide range of potential plots. The plots below highlight the package's versatility.
Here is my attempt. The x-axis is in a discrete variable (i.e., Category). So you cannot use it in geom_text()
. You somehow need to create a numeric variable for the axis. Similarly, you need to find position in the y-axis for labels. In order to get numeric values for the two dimensions, I decided to access to the data frame staying behind your graphic. When you use the ggmosaic
package, there is one data frame behind a graphic in this case. You can get it using ggplot_build()
. You can calculate x and y values using the information in the data frame (e.g., xmin, and xmax). This is good news. But, we have bad news too. When you reach the data, you realize that there is no information about Subcategory that you need for labels.
We can overcome this challenge joining the data frame above with the original data. When I joined the data, I calculated proportion for both the original data and the other data. The values are purposely converted to character. temp
is the data set you need in order to add labels.
library(dplyr)
library(ggplot2)
library(ggmosaic)
# Add proportion for each and convert to character for join
df <- group_by(df, Category) %>%
mutate(prop = as.character(round(Weight / sum(Weight),3)))
# Add proportion for each and convert to character.
# Get x and y values for positions
# Use prop for join
temp <- ggplot_build(g)$data %>%
as.data.frame %>%
transmute(prop = as.character(round(ymax - ymin, 3)),
x.position = (xmax + xmin) / 2,
y.position = (ymax + ymin) / 2) %>%
right_join(df)
g + geom_text(x = temp$x.position, y = temp$y.position, label = temp$Subcategory)
I think you are looking for something like this
library(ggplot2)
library(ggmosaic)
Your data:
Category <- c("Bankpass", "Bankpass", "Bankpass", "Moving", "Moving")
Subcategory <- c("Stolen", "Lost", "Login", "Address", "New contract")
Weight <- c(10,20,13,40,20)
Duration <- as.character(c(0.2,0.4,0.5,0.44,0.66))
Silence <- as.character(c(0.1,0.3,0.25,0.74,0.26))
mydf <- data.frame(Category, Subcategory, Weight, Duration, Silence)
ggplot(data = mydf) +
geom_mosaic(aes( x = product(Duration, Subcategory), fill=factor(Duration)), na.rm=TRUE) +
theme(axis.text.x=element_text(angle=-25, hjust= .1)) +
labs(x="Subcategory", title='f(Duration, Subcategory | Category)') +
facet_grid(Category~.) +
guides(fill=guide_legend(title = "Duration", reverse = TRUE))
The output is:
It is almost the best you can do on ggmosaic
package. You should try other packages.
Good luck for your project work ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With