2

I am trying to create a pie chart for percentage values, when I try to label them the labeling is wrong,

I mean the values are pointing the wrong place in the graph.

ggplot(Consumption_building_type, aes(x="", y=percentage, fill=Building_type))+ geom_bar(width = 0.5,stat ="identity")+coord_polar(theta = "y",direction = -1)+geom_text(aes(x=1.3,y = percentage/3 + c(0, cumsum(percentage)[- length(percentage)]),label = round(Consumption_building_type$percentage,0))) + theme_void()+ scale_fill_brewer(palette="GnBu")+ggtitle("Breakdown of building types")+theme_minimal()

This is the code I used and this is the result I got:

enter image description here
When I change the direction=1 both the graph and the labels shift

the data I used

structure(list(
    Building_type = c("Commercial", "Industrial", "Institutional", "Large residential", 
    "Large Residential", "Residential", "Small residential"), 
    Total_consumption_GJ = c(99665694, 5970695, 10801610, 63699633,
                             16616981, 24373766, 70488556), 
    average_consumption_GJ = c(281541.508474576, 72813.3536585366, 109107.171717172, 
    677655.670212766, 213038.217948718, 123099.828282828, 640805.054545455), 
    total = c(354L, 82L, 99L, 94L, 78L, 198L, 110L), 
    percentage = c(34.8768472906404, 8.07881773399015, 9.75369458128079, 
    9.26108374384236, 7.68472906403941, 19.5073891625616, 10.8374384236453)), 
    .Names = c("Building_type", "Total_consumption_GJ", "average_consumption_GJ", "total", "percentage"), 
     class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -7L)))

Really sorry about the data a new user not sure how to paste the data

G5W
  • 36,531
  • 10
  • 47
  • 80
  • Can you post a reproducible example, i.e. tell us where to get your data or use a public dataset? I tried to do the same steps using the `mpg` dataset but couldn't replicate your problem, changing direction did not change coloring and labels. – hdkrgr Jan 15 '17 at 13:56
  • i used a dataset from [data](https://data.cityofnewyork.us/Environment/Natural-Gas-Consumption-by-ZIP-Code-2010/uedp-fegm/data) calculated the frequency based on types of building and then created a percentage on the frequency then plotted the graph – Karthik Suresh Jan 15 '17 at 14:09
  • Welcome to Stack Overflow! It seems a bit burdensome that we should have to download that data and make the calculations that you made in order to give you help. The usual method is that you should use `dput(Consumption_building_type)` to create a printable version of your data so that we can cut and paste it. – G5W Jan 15 '17 at 16:08
  • structure(list(Building_type = c("Commercial", "Industrial", "Institutional", "Large residential", "Large Residential", "Residential", "Small residential"), Total_consumption_GJ = c(99665694, 5970695, 10801610, 63699633, 16616981, 24373766, 70488556), average_consumption_GJ = c(281541.508474576, 72813.3536585366, 109107.171717172, 677655.670212766, 213038.217948718, 123099.828282828, 640805.054545455), total =c(354L, 82L, 99L, 94L, 78L, 198L, 110L), percentage = c(34.87, 8.07, 9.75, 9.26, 7.68, 19.50, 10.83)) – Karthik Suresh Jan 15 '17 at 16:29
  • @G5W:I did not know that,Sorry,Will use the `dput()` from now – Karthik Suresh Jan 15 '17 at 16:31

1 Answers1

3

Update for ggplot 2.0+

ggplot 2.0+ has some new parameters for position_stack() that make solving this problem much simpler. There's no need to calculate the center point of each bar manually (though that solution may still be preferred in some situations and is therefore preserved below). Instead, we can simply use the "vjust" parameter of position_stack():

g <- ggplot(Consumption_building_type, aes(x="", y=percentage, fill=Building_type))+ 
    geom_bar(width = 0.5,stat ="identity")+
    coord_polar(theta = "y",direction = 1)+
    geom_text(aes(x=1.3,y = percentage, label = round(Consumption_building_type$percentage,0)), position = position_stack(vjust = 0.5)) + 
    scale_fill_brewer(palette="GnBu")+ggtitle("Breakdown of building types")+theme_minimal() +
    labs(x = NULL)

General solution: calculating the midpoint of stacked bars manually

I'm assuming that your goal is to place a label for each bar at the bar's center point. In that case, first we can calculate the center point and add it to the data frame:

Consumption_building_type$zone.start <- with(Consumption_building_type, c(0, cumsum(percentage)[-length(percentage)]))  
Consumption_building_type$zone.end <- with(Consumption_building_type, cumsum(percentage))  
Consumption_building_type$label.point <- with(Consumption_building_type, (zone.start + zone.end) / 2) 

      Building_type Total_consumption_GJ average_consumption_GJ total percentage zone.start zone.end label.point
1        Commercial             99665694              281541.51   354      34.87       0.00    34.87      17.435
2        Industrial              5970695               72813.35    82       8.07      34.87    42.94      38.905
3     Institutional             10801610              109107.17    99       9.75      42.94    52.69      47.815
4 Large residential             63699633              677655.67    94       9.26      52.69    61.95      57.320
5 Large Residential             16616981              213038.22    78       7.68      61.95    69.63      65.790
6       Residential             24373766              123099.83   198      19.50      69.63    89.13      79.380
7 Small residential             70488556              640805.05   110      10.83      89.13    99.96      94.545

And then the y aesthetic in geom_label() is simply the newly created "label.point" column.

I've also added labs(x = NULL) so that there are no empty quote marks on the y-axis of the final plot.

new.plot <- ggplot(Consumption_building_type, aes(x="", y=percentage, fill=Building_type))+ 
    geom_bar(width = 0.5,stat ="identity")+
    coord_polar(theta = "y",direction = 1)+
    geom_text(aes(x=1.3,y = label.point, label = round(Consumption_building_type$percentage,0))) + 
    scale_fill_brewer(palette="GnBu")+ggtitle("Breakdown of building types")+theme_minimal()

enter image description here

jdobres
  • 11,339
  • 1
  • 17
  • 37