0

I am having problems with changing the axis ticks in a barplot. I am fairly new in using ggplot so the answer might be very obvious.

Here is some data (yes it is strange, but designed to mimic the original dataset I have, which I am not allowed to share):

lab='this is just a very long example text and it will be longer and longer and longer and longer and longer and longer and longer and longer and longer and end'
number=1:20
n=unlist(lapply(number,paste,value=lab))
a=round(runif(n=20,min=-48000,max=-40000))
b=round(runif(n=20,min=-48000,max=-40000))
c=round(runif(n=20,min=-48000,max=-40000))
d=data.frame(cbind(n,a,b,c))
df=pivot_longer(d,cols=c('a','b','c'))
l1=round(as.numeric(min(df$value))/1000 )*1000+1000
l2=round(as.numeric(max(df$value))/1000 )*1000-1000
lim=seq(from=l1,to=l2,by=-1000)  
colScale <- scale_fill_manual(name = "n",values = c(rainbow(nrow(df)/3)))

from which I create a barplot

p1=ggplot(df, aes(name, value, fill = as.factor(n))) +
  geom_col(position = "dodge",colour='black') +
  #scale_y_continuous(breaks = lim , labels = as.character(lim)) +
  coord_flip() +
  theme_bw() + 
  theme(axis.text.x=element_text(angle=90),axis.title.x=element_text(face='bold')) +
  theme(axis.text.y=element_text(angle=90,size=15)) +
  theme(legend.title=element_blank()) +
  labs(x = "",y="test") +
  colScale +
  guides(fill=guide_legend(ncol=1)) +
  ggtitle('something') +
  theme(plot.title = element_text(hjust = 0.5,size=20)) 

which is this

that is basically working as I wanted, but the scaling of the x-axis is very unpleasant. What I want instead is an axis, where the breaks and labels are equal to the vector 'lim'. What I understood was that it should be possible to do this by scaling the respective axis as in the commented line. But when I'm trying this I get the error 'Discrete value supplied to continuous scale'. I tried to change the scale to 'scale_y_discrete' but then the ticks disappear completely. I tried everything I could find but nothing worked, so what is wrong?

Based on the answers I changed the plot definition to:

p1=ggplot(df, aes(name, as.numeric(value), fill = as.factor(n))) +
  geom_col(position = "dodge",colour='black') +
  scale_y_continuous(breaks = lim , labels = as.character(lim)) +
  coord_flip() +
  theme_bw() + 
  theme(axis.text.x=element_text(angle=90),axis.title.x=element_text(face='bold')) +
  theme(axis.text.y=element_text(angle=90,size=15)) +
  theme(legend.title=element_blank()) +
  labs(x = "",y="test") +
  colScale +
  guides(fill=guide_legend(ncol=1)) +
  ggtitle('something') +
  theme(plot.title = element_text(hjust = 0.5,size=20)) 

which produced this plot

now I am able to change the axis ticks, but the plot looks nothing like the first one. My goal is to keep the look, meaning showing only the top part of the bars.

tasel
  • 3
  • 4
  • What's `cols25` from? – Jon Spring Feb 19 '21 at 16:55
  • Sorry, that is a colorpalette from the pals package, I changed it to rainbow to make the example runnable without packages – tasel Feb 19 '21 at 16:57
  • 1
    Convert your `value` variable to a numeric, i.e. use `as.numeric(value)`. – stefan Feb 19 '21 at 17:01
  • With that I am able to change the axis, but is there a way to keep the rest of the look from the original example? Specifically only showing the relevant part of the bars which is inside the given limits? – tasel Feb 19 '21 at 17:30
  • It's unclear what you're going for. Do you want the "value" field to be treated like categories (aka Apple Banana Chihuahua) or as numbers? Your `lim` suggests you're thinking of them as numbers on a scale, but your original chart treats them as categories. – Jon Spring Feb 19 '21 at 17:31
  • "Value" should be a numeric scale – tasel Feb 19 '21 at 17:38

1 Answers1

0

I'd suggest converting value to as.numeric (preferably before ggplot, but you can do it within, like below) and using coord_cartesian to specify the "view window". You also might find it simpler to specify your axes in the order you want them, rather than using coord_flip, which is mostly unnecessary since ggplot 3.3.0.

ggplot(df, aes(as.numeric(value), name, fill = as.factor(n))) +
  geom_col(position = "dodge",colour='black') +
  scale_x_continuous(breaks = lim , labels = as.character(lim)) +
  coord_cartesian(xlim = c(min(as.numeric(df$value)), max(as.numeric(df$value)))) 
# Theming after this up to you
Jon Spring
  • 55,165
  • 4
  • 35
  • 53