4

How do I make a plot in R so that the value of a variable displays along the X axis and the variable names go vertically along the Y axis? Ultimately, the plot should look vertical with the variable names on the Y axis and its values on the X axis.

The code below will ostensibly do it, but the problem is the actually plot values do not flip with the axes. Meaning, the plot still constructs as if the names are along the X axis and the values are along the Y axis.

the variables below:

value = a column vector of numbers

name = a column of names that correspond to each number

plot(value, axes=F, xlab="", ylab= "", type= "b", xlim=c(-5, 50), ylim=c(0, 8))
axis(1)
axis(2, at = 1:length(name), labels = name, las=1, pos=-3.0,cex.axis=.65 )

thanks!

agamesh
  • 559
  • 1
  • 10
  • 26
Captain Murphy
  • 855
  • 3
  • 15
  • 23
  • I confess I have absolutely no idea what you could possibly be describing. Could you provide an image of what you want your output to look like? – joran Nov 14 '11 at 23:01
  • Sorry about my description. Here is a much more complicated example (I just want my axes to look this way): http://addictedtor.free.fr/graphiques/RGraphGallery.php?graph=114 – Captain Murphy Nov 14 '11 at 23:11
  • In the link above, notice how the names are on the Y axis and the values are along the X axis. That's all I'd like to do -- plot names on Y and values on X -- and my code above that puts the names on the Y axis and the values on the X axis (in the third line of code), but the actual points in the plot are plotted as if the names are still along the X axis and the values are still on the Y axis. Does that make sense? I just want to flip the X and Y axis and have the data flip with it. – Captain Murphy Nov 14 '11 at 23:13

3 Answers3

7

Once you use a "plot" base function, the user-coordinates are fixed. It's like writing in ink. There is not the possibility of later flipping them with a call to axis. That sort of gymnastics would require a more object oriented approach such as the lattice or ggplot systems. They allow creation of an object that can be updated or amended. If you had a ggplot object you could do something like:

 p + coord_flip()
IRTFM
  • 258,963
  • 21
  • 364
  • 487
5

For easy flexibility in this regard, I like the plotting functions in the lattice package:

 library(lattice)

 # First make some example data
 df <- data.frame(name=rep(c("a", "b", "c"), each=5), value=rnorm(15))

 # Then try plotting it in both 'orientations'
 # ... as a dotplot
 xyplot(value~name, data=df)
 xyplot(name~value, data=df)

 # ... or perhaps as a 'box-and-whisker' plot
 bwplot(value~name, data=df)
 bwplot(name~value, data=df)

If you need to, you can also plot this with base graphics, though you'll have to work a bit on the axis labels:

plot(x=df$value, y=df$name, yaxt="n",
     xlab="value", ylab="name")
axis(2, at=1:3, labels=levels(df$name), las=1)
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • This is great, thanks! Do you know of a way to sort the data so that the values are decreasing or increasing? Like the code `sort(value, decreasing=F)` but for within the plot? the xyplot seems to sort alphabetically by default. Also, is it possible to do axes=F and add them later so that it doesn't look like a box? Thanks again! – Captain Murphy Nov 14 '11 at 23:33
  • 1
    Sure. You'll want to make `name` a factor, and set its `level`s by hand (they default to alphabetical order). To see what I'm talking about, try `factor(df$name)`, then reset the levels with `df$name <- factor(df$name, levels=c("b", "a", "c"))` and replot the figure. Then look at `?factor`, and, if it seems confusing, you'll know that you've got company by having a look at this post: http://stackoverflow.com/questions/7128413/why-is-the-terminology-of-labels-and-levels-in-factors-so-weird – Josh O'Brien Nov 14 '11 at 23:39
  • For setting the levels by hand, does that mean the order of the setting has to match the increasing order? So in your example, b is the smallest, a is the second smallest, and c is the largest. Correct? – Captain Murphy Nov 15 '11 at 00:11
  • Never mind. Got it working! One last question, then I'll leave you alone -- any way to get rid of the box around the graph and add the axes manually like in my original post? This way, only the Y and X axis show. – Captain Murphy Nov 15 '11 at 00:25
  • 1
    That's right, although I'd tend to think of b as 'Level 1', a as 'Level 2', and so on. In this case, we're effectively just telling `R` the order in which we want to plot the levels --- not which one is 'smaller' or 'larger'. – Josh O'Brien Nov 15 '11 at 00:25
  • There doesn't seem to be a `lattice` option to just plot the left and bottom axes. This blog post does lay out a solution, but it's prob more useful once you've used `lattice` for a while: http://thebiobucket.blogspot.com/2011/08/lattice-xyplot-only-with-axes-at-bottom.html . Instead you may want to use the 2nd solution I posted, which has the virtue of leaving you in the more-familiar world of base graphics. – Josh O'Brien Nov 15 '11 at 00:28
  • Gotcha, thanks. I'll just live with the box for now... thanks! – Captain Murphy Nov 15 '11 at 00:38
4

You just got two decent suggestions about using other plotting libraries. I believe your actual problem is that you only pass one vector of values to plot that you intend to be used as x values. But when passed one vector, plot assumes you've given it y values. Just do something like:

plot(x = value, y = 1:length(name),...)

and you should get what you want.

joran
  • 169,992
  • 32
  • 429
  • 468
  • Yes, given that there are no axes that's all the change that's needed. This is the most direct answer to the question. – John Nov 14 '11 at 23:42
  • Thanks, I appreciate it. I tried this way and it does work, thanks! Unfortunately, the layout looks a bit odd given my data, so I'm going with the lattice package xyplot. But you are correct -- this does directly answer my question and it was what I was trying to figure out on my own for hours... – Captain Murphy Nov 15 '11 at 00:26
  • @CaptainMurphy No problem! `lattice` is indeed very nice! – joran Nov 15 '11 at 00:49