-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNested_Column_Bar_Chart.R
More file actions
141 lines (121 loc) · 4.96 KB
/
Nested_Column_Bar_Chart.R
File metadata and controls
141 lines (121 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# This code creates an example Nested Column Chart of the type developed by Brittany Rosenau
# this code will produce the graphic below if you paste it into R Studio and run it
# to run it in a Power BI R visual, just import the csv into Power Query
# and then paste in the code below, changing df <- dataset
# note that "dataset" is the variable name used by convention in Power BI to call the table
# resulting from the previous step
# Load necessary libraries
library(ggplot2)
library(dplyr)
library(readr) # To read the CSV data directly from text
# Recreate the data from the provided CSV text
csv_data <- "Region,Segment,Revenue
West,Consumer,364
West,Corporate,232
West,Home Office,143
East,Consumer,357
East,Corporate,204
East,Home Office,131
Central,Consumer,254
Central,Corporate,158
Central,Home Office,91
South,Consumer,196
South,Corporate,122
South,Home Office,74"
# Read the data into a dataframe
df <- read_csv(csv_data)
# Ensure Region is a factor with the desired order (West, East, Central, South)
df$Region <- factor(df$Region, levels = c("West", "East", "Central", "South"))
# Ensure Segment is a factor with the desired order for legend/coloring
df$Segment <- factor(df$Segment, levels = c("Consumer", "Corporate", "Home Office"))
# Calculate total revenue per region to position total labels and grey background bars
region_totals <- df %>%
group_by(Region) %>%
summarise(TotalRevenue = sum(Revenue), .groups = "drop") # Use .groups='drop' to avoid grouped df issues
# Define custom colors matching the image
segment_colors <- c(
"Consumer" = "#2ECC71", # Green
"Corporate" = "#F39C12", # Orange (or slightly softer like #F5B041)
"Home Office" = "#3498DB"
) # Blue
# Create the plot
p <- ggplot() +
# Layer 1: Grey background bars representing total revenue per region
# Plotted first to be in the background
geom_col(
data = region_totals,
aes(x = Region, y = TotalRevenue),
fill = "grey85", # Light grey fill
alpha = 0.8, # Slightly transparent
width = 0.8
) + # Adjust width if needed
# Layer 2: Dodged bars for segment revenue
geom_col(
data = df,
aes(x = Region, y = Revenue, fill = Segment),
position = position_dodge(width = 0.8), # Dodge bars side-by-side
width = 0.7
) + # Make dodged bars slightly narrower than grey bar
# Layer 3: Labels for individual segment bars ($ Value K)
geom_text(
data = df,
aes(x = Region, y = Revenue, label = paste0("$", Revenue, "K"), group = Segment),
position = position_dodge(width = 0.8), # Match dodging of bars
vjust = -0.5, # Position label above the bar
size = 2.75, # Adjust text size
family = "sans"
) + # Consistent font
# Layer 4: Labels for total region revenue ($ Value K)
geom_text(
data = region_totals,
aes(x = Region, y = TotalRevenue, label = paste0("$", TotalRevenue, "K")),
vjust = -2.0, # Position above the grey bar, adjust vertical position
size = 3.5, # Adjust text size
family = "sans"
) + # Consistent font
# Layer 5: Labels for Region Names (West, East, Central, South)
geom_text(
data = region_totals,
aes(x = Region, y = TotalRevenue, label = as.character(Region)), # Ensure label is character
vjust = -3.5, # Position above the total revenue label
size = 4, # Adjust text size
fontface = "bold", # Make region name bold
family = "sans"
) + # Consistent font
# Apply custom color scale
scale_fill_manual(values = segment_colors) +
# Set plot title
ggtitle("Total Sales by Region and Segment ($K)") +
# Customize the theme to match the image (minimalist, no axes/grid)
theme_void(base_size = 12, base_family = "sans") + # Start with a blank theme, set base font
theme(
# Plot Title Style
plot.title = element_text(
hjust = 0, # Left-align title
face = "bold", # Bold title text
size = 16, # Title font size
margin = margin(b = 15)
), # Margin below title
# Legend Style
legend.position = "top", # Legend at the top
legend.justification = "left", # Left-align legend items
legend.title = element_blank(), # No legend title
legend.text = element_text(size = 11), # Legend text size
legend.key.size = unit(0.5, "cm"), # Size of color keys in legend
legend.margin = margin(b = -10), # Reduce space below legend
# Remove all axis elements (lines, ticks, text) as they are not in the image
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
# Add margin around the plot
plot.margin = margin(20, 20, 20, 20) # Top, Right, Bottom, Left margins
) +
# Adjust y-axis limits to provide space for labels above the bars
# Calculate max height needed (max total revenue + buffer for labels)
# Limit calculation ensures enough space for the highest label (Region Name)
scale_y_continuous(
limits = c(0, max(region_totals$TotalRevenue) * 1.35), # ~35% extra space at top
expand = expansion(mult = c(0, 0))
) # Start y-axis at 0
# Print the plot
print(p)