Ggplot2: replace legend keys and sort alphabetically

I am creating a set of graphs in two languages ​​from ggplot2(Hadley Wikham). I could create them in two separate workflows by renaming the variables inside the original dataset. Instead, I want to change the object ggplot: I want to first create graphics in English, and then translate the labels into French. How to change / change legend keys inside ggplot object? And how can I sort the legend keys?

The reason I am exploring this approach is because I would like my story colors and characters to be the same in English and French, while at the same time having keyed legends in alphabetical order. The problem is that the keys of the French and English legends do not have the same alphabetical order (Spain versus Espagne). Compare the legend keys obtained using MWE : the legend keys are sorted alphabetically in the English legend, but incorrectly in the French legend.

enter image description here

Substitution xlab, ylab, ggtitleand styles change axes labels (for example, the formatting of numbers) is quite simple, so my focus is really on the legend keys and their order listed in the legend.

A MWE , ( group, colour shape ..):

    df <- structure(list(year = c("2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007"), country = c("Australia", "Australia", 
    "Austria", "Austria", "Belgium", "Belgium", "Canada", "Canada", 
    "Denmark", "Denmark", "Finland", "Finland", "France", "France", 
    "Germany", "Germany", "Greece", "Greece", "Italy", "Italy", "Japan", 
    "Japan", "Netherlands", "Netherlands", "New Zealand", "New Zealand", 
    "Norway", "Norway", "Portugal", "Portugal", "Spain", "Spain", 
    "Sweden", "Sweden", "Switzerland", "Switzerland", "United Kingdom", 
    "United Kingdom", "United States", "United States"), value = c(33, 
    33, 33, 33, 30, 30, 34, 34, 30, 30, 33, 33, 28, 29, 27, 27, 40, 
    39, 35, 35, 35, 35, 27, 27, 33, 33, 27, 27, 37, 37, 32, 32, 31, 
    31, 32, 31, 32, 32, 33, 33)), .Names = c("year", "country", "value"
    ), row.names = c(NA, -40L), class = "data.frame")

    library("ggplot2")
    ggplot(data = df, aes(x = year, y = value, group = country, colour = country)) + 
        geom_line(size = 0.5) + geom_point(size = 1)
    ggsave(last_plot(), file = "stackoverflow-1.png")

    ggplot(data = df, aes(x = year, y = value, group = factor(country, labels = c("Australie", "Autriche", "Belgique", "Canada", "Danemark", "Finlande", "France", "Allemagne", "Grèce", "Italie", "Japon", "Pays-Bas", "Nouvelle-Zélande", "Norvège", "Portugal", "Espagne", "Suède", "Suisse", "Royaume-Uni", "États-Unis")), colour = factor(country, labels = c("Australie", "Autriche", "Belgique", "Canada", "Danemark", "Finlande", "France", "Allemagne", "Grèce", "Italie", "Japon", "Pays-Bas", "Nouvelle-Zélande", "Norvège", "Portugal", "Espagne", "Suède", "Suisse", "Royaume-Uni", "États-Unis")))) + geom_line(size = 0.5) + geom_point(size = 1) + theme(legend.title = element_blank())
    ggsave(last_plot(), file = "stackoverflow-2.png")

, , ( ). :

list("A Cuckoo Land" = "Un Pays Idyllique", # This mapping is not used
 "Australia" = "Australie", 
 "Austria" = "Autriche", 
 "Belgium" = "Belgique", 
 "Canada" = "Canada",
 "Denmark" = "Danemark", 
 "Finland" = "Finlande", 
 "France" = "France", 
 "Germany" = "Allemagne", 
 "Greece" = "Grèce", 
 "Italy" = "Italie", 
 "Japan" = "Japon", 
 "Netherlands" = "Pays-Bas", 
 "New Zealand" = "Nouvelle-Zélande", 
 "Norway" = "Norvège", 
 "Portugal" = "Portugal", 
 "Spain" = "Espagne", 
 "Sweden" = "Suède", 
 "Switzerland" = "Suisse", 
 "United Kingdom" = "Royaume-Uni", 
 "United States" = "États-Unis")

. ( , , , , "Belgium" = c("Belgique", "Bélgica").

+4
2

, , . , , , , . :

key <- unlist(list("A Cuckoo Land" = "Un Pays Idyllique", # This mapping is not used
                   "Australia" = "Australie", 
                   "Austria" = "Autriche", 
                   "Belgium" = "Belgique", 
                   "Canada" = "Canada",
                   "Denmark" = "Danemark", 
                   "Finland" = "Finlande", 
                   "France" = "France", 
                   "Germany" = "Allemagne", 
                   "Greece" = "Grèce", 
                   "Italy" = "Italie", 
                   "Japan" = "Japon", 
                   "Netherlands" = "Pays-Bas", 
                   "New Zealand" = "Nouvelle-Zélande", 
                   "Norway" = "Norvège", 
                   "Portugal" = "Portugal", 
                   "Spain" = "Espagne", 
                   "Sweden" = "Suède", 
                   "Switzerland" = "Suisse", 
                   "United Kingdom" = "Royaume-Uni", 
                   "United States" = "États-Unis"))
df_eng <- df
df_fra <- df
df_fra$country <- unlist(key[df_eng$country])

dfs <- list('english' = df_eng,'french' = df_fra)

library("ggplot2")
#Now you can create one "default" plot...
p <- ggplot(data = dfs[['english']], 
            aes(x = year, y = value, 
                group = country, colour = country)) + 
  geom_line(size = 0.5) + 
  geom_point(size = 1)
print(p)

#And simply swap out the data frame...
p %+% dfs[['french']]
+1

, joran / .

, : , , .. . , ggplot , , : , "" , S, , "Espagne" E.

country , , country.fr , . , , .. , , , .

    ### Create a fixed assignment for colors, shapes, linetypes, etc.
    ### The same for both the English and French versions
    ### Data
    df <- structure(list(year = c("2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007", "2006", "2007", "2006", "2007", "2006", 
    "2007", "2006", "2007"), country = c("Australia", "Australia", 
    "Austria", "Austria", "Belgium", "Belgium", "Canada", "Canada", 
    "Denmark", "Denmark", "Finland", "Finland", "France", "France", 
    "Germany", "Germany", "Greece", "Greece", "Italy", "Italy", "Japan", 
    "Japan", "Netherlands", "Netherlands", "New Zealand", "New Zealand", 
    "Norway", "Norway", "Portugal", "Portugal", "Spain", "Spain", 
    "Sweden", "Sweden", "Switzerland", "Switzerland", "United Kingdom", 
    "United Kingdom", "United States", "United States"), value = c(33, 
    33, 33, 33, 30, 30, 34, 34, 30, 30, 33, 33, 28, 29, 27, 27, 40, 
    39, 35, 35, 35, 35, 27, 27, 33, 33, 27, 27, 37, 37, 32, 32, 31, 
    31, 32, 31, 32, 32, 33, 33)), .Names = c("year", "country", "value"
    ), row.names = c(NA, -40L), class = "data.frame")

    ## Create a unique country ID and a language map
    key <- read.table(textConnection("
    AUS,Australia,Australie
    AUT,Austria,Autriche
    BEL,Belgium,Belgique
    CAN,Canada,Canada
    CHE,Switzerland,Suisse
    DEU,Germany,Allemagne
    DNK,Denmark,Danemark
    ESP,Spain,Espagne
    FIN,Finland,Finlande
    FRA,France,France
    GBR,United Kingdom,Royaume-Uni
    GRC,Greece,Grèce
    ITA,Italy,Italie
    JPN,Japan,Japon
    NLD,Netherlands,Pays-Bas
    NZL,New Zealand,Nouvelle-Zélande
    NOR,Norway,Norvège
    PRT,Portugal,Portugal
    SWE,Sweden,Suède
    USA,United States,États-Unis"), 
    sep = ',', stringsAsFactors = FALSE)
    names(key) <- c('country.code', 'country.name', 'country.name.fr')
    ##  Check the types of data
    ##  ! Make sure country is a 'string' not a 'factor' !
    ##  ! otherwise, the 'translation' will be incorrect !
    str(key)
    ##'data.frame': 20 obs. of  3 variables:
    ## $ country.code   : chr  "         AUS" "         AUT" "         BEL" "         CAN" ...
    ## $ country.name   : chr  " Australia" " Austria" " Belgium" " Canada" ...
    ## $ country.name.fr: chr  " Australie" " Autriche" " Belgique" " Canada" ...

    ## Create a unique code variable for each country
    df$country.code <- NA
    matched <- match(df$country, key$country.name)
    df$country.code <- ifelse(is.na(matched), df$country, key$country.code[matched])

    ## translate country name with translation key
    df$country.fr <- NA
    matched <- match(df$country, key$country.name)
    df$country.fr <- ifelse(is.na(matched), NA, key$country.name.fr[matched])

    ## Set the country names to be factors (they are currently strings)
    ## function as.factor orders alphabetically
    # English
    df$country <- as.factor(df$country)
    View(df)
    # French
    df$country.fr <- as.factor(df$country.fr)
    View(df)

    ## Define some colors (here manually combining Set1 and Set3 of RColorBrewer)
    ## The Palette could also have been embedded in the key dataframe earlier...
    colorPalette <- c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999","#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", "#80B1D3", "#FDB462", "#B3DE69", "#FCCDE5", "#D9D9D9", "#BC80BD", "#CCEBC5", "#FFED6F")
    length(colorPalette)  # Make sure we have enough colors
    ## [1] 21

    ## Set the colors to each country within the dataframe
    ## There is no need for that, but I felt it was idiot-proof
    names(colorPalette) <- levels(df$country)
    df$colors <- NA
    matched <- match(df$country, names(colorPalette))
    df$colors <- ifelse(is.na(matched), NA, colorPalette[matched])
    ##'data.frame': 40 obs. of  6 variables:
    ## $ year        : chr  "2006" "2007" "2006" "2007" ...
    ## $ country     : Factor w/ 20 levels "Australia","Austria",..: 1 1 2 2 3 3 4 4 5 5 ...
    ## $ value       : num  33 33 33 33 30 30 34 34 30 30 ...
    ## $ country.code: chr  "AUS" "AUS" "AUT" "AUT" ...
    ## $ country.fr  : Factor w/ 20 levels "Allemagne","Australie",..: 2 2 3 3 4 4 5 5 6 6 ...
    ## $ colors      : chr  "#E41A1C" "#E41A1C" "#377EB8" "#377EB8" ...

    ### Make the English plot
    ##  use the country factor to order variables
    library("ggplot2")
    p <- ggplot(data = df, aes(x = year, y = value, 
                    group = country, colour = country)) + 
      geom_line(size = 0.5) + 
      geom_point(size = 1) +
      guides(colour = guide_legend(ncol = 2))
    p

    ### Swap out the colors with custom scheme using scale_colour_manual
    ## To ensure correct mapping, use named vectors in scale_colour_manual
    colors <- df$colors
    names(colors) <- df$country
    str(colors)
    ## Named chr [1:40] "#E41A1C" "#E41A1C" "#377EB8" ...
    ## - attr(*, "names")= chr [1:40] "Australia" "Australia" "Austria" "Austria" ...

    p + scale_colour_manual(name = "country", values = colors)

    ### Make the French plot
    ##  use the country.fr factor to order variables
    colors.fr <- df$colors
    names(colors.fr) <- df$country.fr
    str(colors.fr)
    ##Named chr [1:40] "#E41A1C" "#E41A1C" "#377EB8" ...
    ## - attr(*, "names")= chr [1:40] "Australie" "Australie" "Autriche" "Autriche" ...
    p <- ggplot(data = df, aes(x = year, y = value, 
                    group = country.fr, colour = country.fr)) + 
      geom_line(size = 0.5) + 
      geom_point(size = 1) +
      guides(colour = guide_legend(ncol = 2))
    p

    p + scale_colour_manual(name = "pays", values = colors.fr)

:

enter image description here

0

All Articles