Change plotting order of an area chart in R

Asked

Viewed 338 times

-1

I am using the following code to try to plot a graph

ggplot(final2, aes(x = final2$a, y =final2$somaacumulada,fill=final2$Country)) +
  theme_bw()+
  geom_area(position = position_dodge(width = 0.8))

This is a part of data frame

"Rated Power","Country","Commissioned","d","m","a","somaacumulada"
1.14,"Resto do mundo","01.01.1985",1,1,1985,17451.5
1.28,"Japan","01.01.1995",1,1,1995,16969.78
1.7,"Resto do mundo","01.01.1966",1,1,1966,2542.3
2,"China","01.11.1992",1,11,1992,485
3.5,"Germany","01.01.1973",1,1,1973,1346.7
3.6,"Spain","01.01.1955",1,1,1955,10.8
4.6,"Resto do mundo","01.01.1957",1,1,1957,238.6
7,"Austria","01.01.1969",1,1,1969,352
7.2,"Spain","01.01.1929",1,1,1929,7.2
8.5,"United States","01.01.1954",1,1,1954,37.5
11,"France","01.01.1951",1,1,1951,11
11.3,"Spain","27.06.2014",27,6,2014,6758.7
12,"India","01.01.1976",1,1,1976,162
13.5,"Japan","01.01.1961",1,1,1961,13.5
14,"Spain","01.01.1966",1,1,1966,339.8
15.9,"Resto do mundo","01.01.1969",1,1,1969,2758.2
17,"Resto do mundo","01.01.1986",1,1,1986,18791.5
22,"China","01.11.1973",1,11,1973,63
24,"Resto do mundo","01.01.1953",1,1,1953,234
25.2,"United States","01.01.1973",1,1,1973,6518.7
28,"United States","01.01.1972",1,1,1972,5277.5
29,"United States","01.01.1929",1,1,1929,29
30,"Resto do mundo","01.01.1937",1,1,1937,165
30.8,"Resto do mundo","01.01.1989",1,1,1989,20912.3
35,"Germany","01.01.1959",1,1,1959,404
36.5,"Italy","01.01.1965",1,1,1965,489.7
37,"Resto do mundo","31.12.2016",31,12,2016,33017.7
40,"Resto do mundo","01.01.1974",1,1,1974,5482.2
40,"United States","14.09.2012",14,9,2012,22560.7
41,"China","01.05.1968",1,5,1968,41
42,"Italy","01.01.1968",1,1,1968,646.7
45,"Resto do mundo","01.01.1944",1,1,1944,210
45,"United States","01.01.1994",1,1,1994,21425.7
48,"France","01.01.1957",1,1,1957,59
49,"Germany","01.01.1983",1,1,1983,3999.7
49.2,"Germany","01.01.1960",1,1,1960,453.2
50,"Austria","01.01.2011",1,1,2011,3200
50,"United States","01.08.1971",1,8,1971,5249.5
53,"Resto do mundo","01.01.1990",1,1,1990,20965.3
54,"Spain","01.01.1982",1,1,1982,2561.3
58,"United States","01.01.1984",1,1,1984,15300.9

However I am not able to make the order of the areas right, the larger areas that are in front of the graph and hide the smaller ones that are behind, someone would know a way to solve this?inserir a descrição da imagem aqui

Another question I have would be to limit the values on the X axis to have a range that better represents the graph.

EDIT --

I made the following editions:

final2$Country <- factor(final2$Country, levels = c('Resto do mundo','United States','Japan','China','Italy','Germany','Spain','France','India','Austria'))

ggplot(final2, aes(x = Commissioned, y =somaacumulada)) +
  theme_bw()+
  geom_area(position = position_dodge(width = 0.8),alpha=1, aes(fill=Country)) +
  scale_x_date(breaks= "10 years", labels = date_format("%Y"))+
  scale_y_continuous(breaks=seq(0,37000,1000)) +
  xlab('Ano') +ylab('Potência Instalada [MW]')

And I got the following result inserir a descrição da imagem aqui

however the result is not suitable, still has some hidden values and, as I am using accumulated sum, the values of any country should not decrease from one year to another, or increases or remains constant.

  • 1

    In aes(...) doesn’t need final2$. Remove and try again.

  • 1

    Always try to leave a playable example, so you can receive a response. The area overlay problem, try to sort the data with arrange or equivalent. For the x-axis limit, try coord_cartesian(xlim = c(limite inferior, limite superior)).

  • 2

    @Alexandresanches Or filter the zeros, by the appearance of the graph there are zeros until after 1950.

  • 1

    you can change the opacity through alpha

  • @Alexandresanches I didn’t understand what you meant by the reproducible example. I thank you for the limit code, it worked perfectly! There are no zeroes after 1950, what happens is that some data remains constant until 2019.

  • @Bruno Thanks! I was using the opacity to be able to see the hidden data, but in their precise final product with opacity 0

  • 2

    Always try to post a reproducible example so we can replicate your data and come up with solutions. For example, you posted your code, but I can’t test it in my version of R because I don’t have the data and you didn’t put any example data.

  • @Ruibarradas I did what you said and I got the same result.

  • @Alexandresanches I entered a part of the data

Show 4 more comments

1 answer

3


Here are two solutions to the problem. Both order the countries of the largest somaacumulada for the smallest but do it in different ways and the final orders are different. In both solutions Country becomes a class column "factor", different levels depending on the order of somaacumulada.

1. Load the package ggplot2 and turn dates into true dates.

library(ggplot2)

final2$Commissioned <- as.Date(final2$Commissioned, "%d.%m.%Y")

2. First solution.

This solution orders countries by date of Commissioned and somaacumulada.

  1. Create an index i;
  2. Create a level vector for the factor Country by order of i.
  3. Create the factor with these levels.

The result is that we have the largest accumulated sums to last date in the background, then the big seconds, etc. The smaller areas are in the foreground but only those that reach the last day.

i <- with(final2, order(Commissioned, somaacumulada, decreasing = TRUE))
lvls <- unique(final2$Country[i])
final2$Country <- factor(final2$Country, levels = lvls)

ggplot(final2, aes(x = a, y = somaacumulada, fill = Country)) +
  geom_area(position = position_dodge(width = 0.8)) +
  theme_bw()

inserir a descrição da imagem aqui

3. Second solution.

Now the countries are ordered by somaacumulada without taking into account the dates. The graphic instructions are exactly the same.

m <- with(final2, tapply(somaacumulada, Country, max))
m <- sort(m, decreasing = TRUE)
lvls <- unique(names(m))
final2$Country <- factor(final2$Country, levels = lvls)

ggplot(final2, aes(x = a, y = somaacumulada, fill = Country)) +
  geom_area(position = position_dodge(width = 0.8)) +
  theme_bw()

inserir a descrição da imagem aqui

Editing

To answer the question under review, how to add one line per country for the year 2019 with the same data as the last row for that country, if there is no data yet for 2019, the following code is a solution in R base.

ano <- 2019
d.ano <- as.Date(paste(ano, 1, 1, sep = '-'))
sp <- split(final2, final2$Country)

sp <- lapply(sp, function(X){
  n <- nrow(X)
  if(X[n, 'a'] < ano){
    new <- X[n,, drop = FALSE]
    new$Commissioned <- d.ano
    new$d <- 1
    new$m <- 1
    new$a <- ano
  }
  rbind(X, new)
})
novo <- do.call(rbind, sp)
row.names(novo) <- gsub('[^[:digit:]]+', '', row.names(novo))
novo <- novo[order(as.integer(row.names(novo))), ]
novo
  • Thank you so much for the answers, you helped me a lot!! Now a question, would you have an easier way to put the values that do not have data for the year 2019 as constant until 2019? By my little knowledge I would add one more line in the dataframe with the 2019 date for Italy, for example, and repeat the last cumulative column value to make it constant, I would do this for all other cases. There’s an easier way to do that?

  • 1

    @Matheusdias This is a different question but I will edit with a way to do this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.