0

I have a questionnaire that contains answers with large text and I am not able to generate my graphs for analysis.

The graphics always come out with the text completely unformatted. I've tried using [![axis.text.x = element_text (angle = 90, hjust = 1)][1]][1] but it didn't work.

enter image description here

My dataset: http://www.sharecsv.com/s/b0bad3c5144e5b5f70fd90b6f99413a3/q8.csv

structure(list(Artefatos = structure(10:1, .Label = c("Catálogo dos Sistemas Informatizados (Catálogo de Serviços de TIC - Acordo de Nível de Serviços e Métricas e Indicadores para Desempenho dos Serviços e Acordos de Nível de Serviço)", 
"Contratação de Bens e Serviços de TIC (Gerenciar Aquisições de Software)", 
"Gerenciar Ativos de TIC (Hardware,Licenças e Custos)", "Gestão de Riscos de Segurança da Informação", 
"Gestão de Riscos de TIC", "Modelagem de Processos de Negócio (Automatizados/a Automatizar)", 
"Processo de Desenvolvimento de Software (Gerenciamento da Qualidade,Configuração)", 
"Processo de Gerenciamento de Incidentes e Problemas (Central de Serviços)", 
"Processo de Gerenciamento de Mudanças", "Processo de Gestão de Contratos de TIC"
), class = "factor"), counts = c(7L, 2L, 4L, 5L, 2L, 5L, 5L, 
6L, 9L, 5L), prop = c(14, 4, 8, 10, 4, 10, 10, 12, 18, 10), lab.ypos = c(7, 
16, 22, 31, 38, 45, 55, 66, 81, 95), prop_desenv = c(70, 20, 
40, 50, 20, 50, 50, 60, 90, 50)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -10L))

My analyses code:

q8 <- read.csv("q8.csv", 
               header = TRUE, 
               quote="\"",
               sep=",",
               stringsAsFactors= TRUE,
               strip.white = TRUE,
               encoding = "UTF-8")

titulo <- "my title"

#seleciona atributo e realiza contagem
df <- q8 %>%
  group_by(QUESTAO8) %>%
  rename (Artefatos = QUESTAO8) %>% 
  summarise(counts = n()) %>%
  arrange(desc(Artefatos)) %>%
  mutate(prop = round(counts*100/sum(counts), 1),
         lab.ypos = cumsum(prop) - 0.5*prop,
         prop_desenv = (prop*100)/(nrow(Answers)*100/nrow(q8)))

#mostra os dados do atributo
sprintf("Quantidade de registros: %d", nrow(q8))
df

#plota o atributo
ggplot(df, aes(x = Artefatos, y = counts)) +
  geom_bar(
    aes(color = Artefatos, fill = Artefatos),
    stat = "identity", position = position_stack()
    )+
  xlab(titulo)+
  ylab("Amount")+ 
  theme(axis.text.x = element_blank())


ggplot(df, aes(x = Artefatos, y = counts)) +
  geom_bar(fill = "#0073C2FF", stat = "identity") +
  xlab(titulo)+
  ylab("Amount")+ 
  theme(axis.text.x = element_text(angle = 90))


#percentual em relacao ao total de itens
ggplot(df, aes(x = Artefatos, y = prop_desenv)) +
  geom_bar(
    aes(color = Artefatos, fill = Artefatos),
    stat = "identity", position = position_stack()
    )+
  xlab(titulo)+
  ylab("Percentage of Artefacts")+ 
  theme(axis.text.x = element_blank())

#percentual em relacao ao total de itens
ggplot(df, aes(x = Artefatos, y = prop_desenv)) +
  geom_bar(
    aes(fill = Artefatos),
    stat = "identity", position = position_stack()
    )+
  xlab(titulo)+
  ylab("Percentage of Artefacts")+ 
  theme(axis.text.x = element_blank())


#percentual em relacao ao total de respostas
ggplot(df, aes(x = "", y = prop, fill = Artefatos)) +
  geom_bar(width = 0.7, stat = "identity", color = "white") +
  geom_text(aes(y = lab.ypos, label = prop), color = "black") +
  ylab("Proportion")+ 
  xlab(titulo)


ggplot(df, aes(x = "", y = prop, fill = Artefatos)) +
  geom_bar(width = 1, stat = "identity", color = "white") +
  geom_text(aes(y = lab.ypos, label = prop), color = "white") +
  coord_polar("y", start = 0) +
  ylab("Proportion")
Leomar de Souza
  • 677
  • 10
  • 23
  • What are hoping to do? It might be easiest if you have come up with clear acronyms for each and including a "lookup" in a footnote or table. – r2evans May 21 '20 at 04:42
  • @r2evans I need the labels on the graphics, because depending on the image, there is no space for the graphics when the texts are large. Even if they are big. Maybe your solution will work and so I will research it – Leomar de Souza May 21 '20 at 14:37
  • Can you post your dataset as the result of `dput(df)` instead of the link to the .csv? I cannot access the link. – chemdork123 May 21 '20 at 15:00
  • @chemdork123 done – Leomar de Souza May 21 '20 at 15:11

2 Answers2

1

Given your clarification and dataset, I still think the best option is to shorten at least the longest of the titles - use an abbreviation if possible for at least some of the words - however, this was the best I could do with a bit of fiddling around.

First, I do want to point out the following suggestions regarding your ggplot code:

  • I think the code you posted lacked quotes around "titulo" within xlab()

  • No need for position=position_stack() within geom_bar. There's no grouping, so there's nothing to stack.

  • No need to define color= in geom_bar when you've defined fill=, especially when they are going to be the same. It doesn't break anything, but may cause unintentionally a separation of those two legends if you change an aspect of one but not the other.

Now, for the adjustments, I present two options. To wrap the labels, I'm using str_wrap() from the stringr library. As mentioned, you can also use wrap_format() in scales - or write your own custom function.

Option 1: Labeled Legend to the Right

For this option, I call str_wrap() right in the aes(fill= call for geom_bar to cause the legend labels to wrap. I am also adjusting the legend.key.height to accomodate the now multi-line labels. Finally, since the chart is rotated with coord_flip(), You will want to reverse the order of df$Artefatos by scale_x_discrete. It's still the "x axis" for scale_ calls, even though it's considered the y axis for theme specifications:

ggplot(df, aes(x = Artefatos, y = counts)) +
  geom_bar(aes(fill = str_wrap(Artefatos, 50)), stat = "identity") +
  labs(x='titulo', y='Amount',
    title='Awesome and Informative Title Goes Here',
    fill='Legend Title Here'
  ) +
  theme(
    axis.text.y = element_blank(),
    legend.key.height = unit(1,'cm')
  ) +
  scale_x_discrete(limits = rev(levels(df$Artefatos))) +
  coord_flip() 

enter image description here

Option 2: No Legend and Wrap Axis Text

This is my preferred option, since it doesn't make too much sense to have the colored boxes twice, when you can just label the axis. Here, the wrapping of text happens within scale_x_discrete (because the plot is rotated with coord_flip()). We have to suppress creation of the legend, which I'm doing through show.legend=FALSE within geom_bar. Additionally, I messed around with size and alignment of text, as well as size. Note that the plot will look different depending on aspect ratio, so you should resize the plot window to see how it affects your changes and use that aspect ratio and resolution when saving the plots.

ggplot(df, aes(x = Artefatos, y = counts)) +
  geom_bar(
    aes(fill = Artefatos), stat = "identity",
    show.legend=FALSE
  ) +
  labs(
    x='titulo', y='Amount',
    title='Awesome and Informative Title Goes Here'
  ) +
  theme(axis.text.y = element_text(hjust=1, vjust=0.5, size=8)) +
  scale_x_discrete(
    limits = rev(levels(df$Artefatos)),
    labels=str_wrap(df$Artefatos, 50)
  ) +
  coord_flip()

enter image description here

chemdork123
  • 12,369
  • 2
  • 16
  • 32
0

Seems you want to wrap axis text labels. The method I use for long labels in order to automatically wrap across multiple lines is the answer down in that question using the scales library and wrap_format(). You probably also will want to angle your axis labels for very long text. Something like this could work if added to your ggplot2 object:

theme(axix.text.x = element_text(angle=90, hjust=1, vjust=0.5) +
scale_x_discrete(labels = wrap_format(12))

Note that you will want the vjust=0.5 argument added to the element_text() call, since the default aligns text at the top (good for horizontal), whereas you want it vertically aligned in the middle (good for angled text). Sometimes angle=45 or another shallow angle can fit more text in axis labels.

Finally, @r2evans had a good suggestion to use abbreviations for long text in axis labels where possible.

chemdork123
  • 12,369
  • 2
  • 16
  • 32