Home > OS >  Using logarithmic axes for graphs with very big or very small values ggplot R
Using logarithmic axes for graphs with very big or very small values ggplot R

Time:09-02

I have a chart with countries that have different associated percentages.

One of the countries has a very large percentage, the rest very small. I create a chart in ggplot and then convert it to a plotly object with ggplotly():

enter image description here

However, I then have the problem of the other country percentages being so small that they're not really visually useful, and some of them also do not display tooltips if hovered over. So, I decided to convert the x-axis to a log10 scale, but:

enter image description here

This is obviously incorrect. How can I convert the x-axis correctly into a logarithmic scale?

I will admit that I'm not super familiar with log/log10, so any help would be appreciated.

Reproducible code:

df <- data.frame(
  country = c("Australia", "United Kingdom", "United States", "China", "Ukraine", "New Zealand"),
  percentage = c(0.98, 0.002, 0.005, 0.007, 0.003, 0.003)
)


# Without logarithmic transformation
x <- df %>% ggplot(
  aes(
    x = percentage,
    y = reorder(country, -percentage),
    fill = country
  )
)   geom_bar(stat = "identity")

ggplotly(x)


# With logarithmic transformation

x <- df %>% ggplot(
  aes(
    x = percentage,
    y = reorder(country, -percentage),
    fill = country
  )
)   
  geom_bar(stat = "identity")  
  scale_x_log10()

ggplotly(x)

CodePudding user response:

The log of values less than 1.0 is negative, and ggplot treats 0 as the origin point for bar plots. This creates the confusing plot you have so far. We can get around these limitations by multiplying the percentages by 1000 and then specifying some custom labeling.

Strictly speaking, this isn't a perfect solution, since we are introducing some additional distortion into the data. I would recommend exploring other ways to display these data, given the order of magnitude difference between one country and the others.

df %>% 
  ggplot(
  aes(
    x = percentage * 1000,
    y = reorder(country, -percentage),
    fill = country
  )
)   
  geom_bar(stat = "identity")  
  scale_x_log10(labels = \(x) x / 10)  
  labs(x = 'Percentage', y = 'Country')

enter image description here

  • Related