Lexal
Lexal

Reputation: 35

Adjusting the y-axis in ggplot (bar size, ordering, formatting)

I have the following data.table:

Text

I would like to have a plot which shows the columns symbol and value in a box plot. The boxes should be ordered by the column value.

My code, that I've tried:

plot1 <- ggplot(symbols, aes(symbol, value, fill = from)) +
  geom_bar(stat = 'identity') +
  ggtitle(paste0("Total quantity traded: ", format(sum(symbols$quantity), scientific = FALSE, nsmall = 2, big.mark = " "))) +
  theme_bw()
plot1

This returns the following plot: Text

What I would like to change: - flip x- and y-axis - show the correct height of boxes (y-axis)...currently the relation between the boxes is not correct. - decreasing order of the boxes by columns value - format the y-axis with two digits - make the x-axis readable...currently the x-axis is just a long bunch of what is written in column symbol.

Thanks upfront for the help!

Upvotes: 0

Views: 112

Answers (1)

chemdork123
chemdork123

Reputation: 13843

To make things a bit easier, it is suggested that you post your data frame as the output of dput(your.data.frame), which presents code that can be used to replicate your dataset in r.

With that being said, I recreated your data (it was not too big)--some numbers were rounded a bit to make things easier.

A few comments:

  • y-axis numbers are odd: The numbers on your y-axis are not numeric. If you type str(your.data.frame) you'll probably notice that "value" is not numeric, but a character or factor. This can be easily remedied via: df$value <- as.numeric(df$value), where df is your dataframe.

  • flipping axis: You can use coord_flip() (typically added to the end of your ggplot call. Be warned that when you do this, your aesthetics flip for the plot, so just keep that in mind.

  • your dataframe name is also a function/data name in r: This may not be causing any issues (due to your environment), but just be aware to use caution to name your dataset to not have names that are used in r elsewhere. This goes for column/variable names too. I don't think it causes any issues here, but just an FYI

  • geom_col vs geom_bar: Check out this documentation link for some description on the differences between geom_bar and geom_col. Basically, you want to use geom_bar when your y-axis is count, and geom_col when your y-axis is a value. Here, you want to plot a value, so choose geom_col(), and not geom_bar().

Fixing the issues in plot

Here's the representation of your data (note I rounded... hopefully got the actual data correct, because I manually had to copy each value):

   from  symbol  quantity      usd    value
1   BTC BTCUSDT 12910.470 6776.340 87485737
2   ETH ETHUSDT  6168.730  154.398   952445
3   BNB BNBUSDT 51002.650   14.764   753017
4   BNB  BNBBTC 31071.280   14.764   458745
5   ETH  ETHBTC  2216.576  154.398   342236
6   LTC LTCUSDT  4332.024   40.481   175368
7   BNB  BNBETH  3150.030   14.764    46507
8   LTC  LTCBTC   922.560   40.481    37346
9   LTC  LTCBNB   521.476   40.481    21110
10  NEO NEOUSDT  2438.353    7.203    17564
11  NEO  NEOBTC   417.930    7.203     3010

Here's the basic plot, flipped:

ggplot(df, aes(symbol, value, fill=from)) +
    geom_col() +
    coord_flip()

enter image description here

The problem here is that when you plot values... BTCUSDT is huge in comparison. I would suggest you plot on log of value. See this link for some advice on how to do that. I like the scale_y_log10() function, since it just works here pretty well:

ggplot(df, aes(symbol, value, fill=from)) +
    geom_col() +
    scale_y_log10() +
    coord_flip()

enter image description here

If you wanted to keep the columns going in the vertical orientation, you can still do that and avoid having the text run into each other on the x-axis. In that case, you can rotate the labels via theme(axis.text.x=...). Note the adjustments to horizontal and vertical alignment (hjust=1), which forces the labels to be "right-aligned":

ggplot(df, aes(symbol, value, fill=from)) +
    geom_col() +
    scale_y_log10() +
    theme(axis.text.x=element_text(angle=45, hjust=1))

enter image description here

Upvotes: 2

Related Questions