How to make 3D plots with categorical data in R?

2020-07-14 12:09发布

问题:

I've been trying to create a 3D bar plot based on categorical data, but have not found a way.

It is simple to explain. Consider the following example data (the real example is more complex, but it reduces to this), showing the relative risk of incurring something broken down by income and age, both categorical data.

I want to display this in a 3D bar plot (similar in idea to http://demos.devexpress.com/aspxperiencedemos/NavBar/Images/Charts/ManhattanBar.jpg). I looked at the scatterplot3d package, but it's only for scatter plots and doesn't handle categorical data well. I was able to make a 3d chart, but it shows dots instead of 3d bars. There is no chart type for what I need. I've also tried the rgl package, but no luck either. I've been googling for more than an hour now and haven't found a solution. I have a copy of the ggplot2 - Elegant Graphics for Data Analysis book as well, but ggplot2 doesn't have this kind of chart.

Is there another freeware app I could use? OpenOffice 3.2 doesn't have this chart either.

Thank you for any hints.

Age,Income,Risk
young,high,1
young,medium,1.2
young,low,1.36
adult,high,1
adult,medium,1.12
adult,low,1.23
old,high,1
old,medium,1.03
old,low,1.11

回答1:

I'm not sure how to make a 3d chart in R, but there are other, better ways to represent this data than with a 3d bar chart. 3d charts make interpretation difficult, because the heights of the bars and then skewed by the 3d perspective. In that example chart, it's hard to tell if Wisconsin in 2004 is really higher than Wisconsin 2001, or if that's an effect of the perspective. And if it is higher, how much so?

Since both Age and Income have meaningful orders, it wouldn't be awful to make a line graph. ggplot2 code:

ggplot(data, aes(Age, Risk, color = Income))+
  geom_line(aes(group = Income))

Or, you could make a heatmap.

ggplot(data, aes(Age, Income, fill = Risk)) +
  geom_tile()


回答2:

Like the others suggested there are better ways to present this, but this should get you started if you want something similar to what you had.

df <-  read.csv(textConnection("Age,Income,Risk
young,high,1
young,medium,1.2
young,low,1.36
adult,high,1
adult,medium,1.12
adult,low,1.23
old,high,1
old,medium,1.03
old,low,1.11
"))
df$Age <- ordered(df$Age, levels=c('young', 'adult', 'old'))
df$Income <- ordered(df$Income, levels=c('low', 'medium', 'high'))
library(rgl)
plot3d(Risk ~ Age|Income, type='h', lwd=10, col=rainbow(3))

This will just produce flat rectangles. For an example to create nice looking bars, see demo(hist3d).



回答3:

You can find a starting point here but you need to add in more lines and some rectangles to get a plot like you posted.