How can you visualize the relationship between 3 categorical variables? I have a dataset with three categorical variables and I want to visualize the relationship between all three in one graph. Any ideas?
Currently I am using the following three graphs:

Each graph is for a level of baseline depression (Mild, Moderate, Severe). Then within each graph I look at the relationship between treatment (0,1) and Depression improvement (none, moderate, substantial). 
These 3 graphs work to see the 3-way relationship, but is there a known way to do this with one graph?
 A: Isn't Mosaic plot specially designed for this purpose? 
In R it would be like 
library(vcd)
d = read.table("data.dat", header=TRUE)
tab = xtabs(frequency ~ treatment+baseline+improvement, data=d)
mosaic(data=tab,~ treatment+baseline+improvement, shade=TRUE, cex=2.5)

Each categorical variables goes to one edge of the square, which is subdivided by its labels. (Thus, if you subdivide each edge at one level only, at most 4 categorical variables can be represented. IMHO, beyond 3 it becomes messy and harder to interpret). The size of the rectangles is proportional to frequency. This is the main idea behind mosaic plot and it is the same in this answer and the answer of Paweł Kleka.  
The differences are in layouts of those rectangles and "niceties" provided by a specific R-package used for this type of plot. As you see from the answer of Paweł Kleka, the graphics package subdivides the upper edge at 2 levels instead of using the right edge. I used vcd package with default options, so that color indicates the degree of association between the variables. Grey means that data are consistent with (you cannot reject the hypothesis of) variable independence. Blue means that positive association exist between "severe" baseline and "substantial" improvement for both "0" and "1" treatment. (Surprise, surprise! I translate it as follows: if you have a severe depression, you will likely get substantially better whether you have a treatment or not. Correct me if I am wrong.)
One can adjust the plot according to one's needs, see, for example, here. The package also has several vignettes, google "vcd mosaic example" (as I just did). Wikipedia article cited at the very beginning also explains how to construct this type of plot and intuition behind it.

When you compare my picture with the picture in the answer of Paweł Kleka, it does not matter, that 'treatment' is on the left edge of each picture. You can easily change the edge location by changing the last line of my code and adjust the layout according to your needs. The common practice is that to the left goes the most important variable or the variable with the least number of labels. You can also change the order of labels (for example, so, that at the right edge the order is "none moderate substantial") by making the corresponding factor variable in R ordered and adjusting its levels. 
A: I'm fond of using a 2-level x-axis for data like this. So your x-axis categories for a  single chart might be:


*

*Treatment=0, Baseline=Mild

*Treatment=0, Baseline=Moderate

*Treatment=0, Baseline=Severe

*Treatment=1, Baseline=Mild

*Treatment=1, Baseline=Moderate

*Treatment=1, Baseline=Severe


...with the same counts by categories [none/moderate/substantial] histogram  bars.
A: The information can also be conveyed using following simple line chart: 

The improvement is shown by different line types while the baseline group is shown in colors. These and the x-axis parameter (treatment here) can also be interchanged if desired. 
A: I sugest use mosaic plot
mosaicplot(table(moz), sort = c(3,1,2), color = T)


A: An option I'd consider is to use parallel sets. Some of the comparisons will be easier than others, but you can still see the relations among three categorical variables. 
Here it is an example with Titanic Survival data:

In R (given your tags) I have used ggparallel for implementing it. Some folks have discussed here on CV how to implement it in other ways.  
A: This is an interesting data set to try to represent graphically, partly because it's not really categorical. Both 3-level factors are ordinal and there is possible interplay between them (presumably, it's harder for a mild baseline to have substantial improvement -- or maybe substantial improvement means something different for each baseline).
With multiple variables, there isn't usually a single view that shows all the features you might care about. Some factors will be easier to compare than others. I think your original view is good and would be better with Nick Cox's suggestions: removing duplicate legends and using an ordinal color scale.
If you're most interesting in seeing the difference between treatments, you can emphasize the change by using a stacked area plot instead of stacked bars.

I'm usually wary of stacking in general because it's harder to read the middle values, but it does re-enforce the fixed-sum nature of this data. And it makes it easy to read the sum moderate+substantial if that's relevant. I've flipped the order of the improvement levels so that higher is better for the frequency.
Without stacking, the equivalent is a slope graph.

It's easier to read each level, but harder to understand the interplay. You have to keep in mind that the third line is directly dependent on the other two.
Given the ordinal nature of the data, it may be helpful to convert the improvement value into a numeric score, as is often done with Likert data. For instance, none=0, moderate=1, substantial=2. Then you can graph that variable on a continuous scale. The downside is that you have to find a reasonable scoring (e.g., maybe 0, 1 and 5 would be a truer representation).

Colophon: These plots were made with the Graph Builder feature in the software package JMP (which I help develop). Though made interactively, a script, for instance, for the area plot, without the coloring customizations, is:
Graph Builder(
    Graph Spacing( 15 ),
    Variables( X( :treatment ), Y( :frequency ),
        Group X( :baseline ), Overlay( :improvement )
    ),
    Elements( Area( X, Y ) )
);

A: First, here is my reading from the graph provided of the data for those who wish to play (experiment, if you like). NB off-by-one errors are certainly possible, as are gross errors. 
    improvement  treatment   baseline   frequency  
           none          0       mild          5  
       moderate          0       mild         41  
    substantial          0       mild          4  
           none          1       mild         19  
       moderate          1       mild         19  
    substantial          1       mild         12  
           none          0   moderate         19  
       moderate          0   moderate         24  
    substantial          0   moderate          7  
           none          1   moderate         20  
       moderate          1   moderate         14  
    substantial          1   moderate         16  
           none          0     severe          7  
       moderate          0     severe         21  
    substantial          0     severe         22  
           none          1     severe         12  
       moderate          1     severe         15  
    substantial          1     severe         23  

Here is a reworking of the original design. One detail of the original data makes things simple: the number of people in each of the predictor combinations is the same, so plotting frequencies and plotting percents are the same. Here instead of a stacked (subdivided, segmented) bar chart, we separate out bars in a two-way bar chart or table plot design. 
Much of the detail in graphics is just that, detail. Several small weaknesses in a graph can undermine its effectiveness and several small improvements can help too. 

To spell it out: 


*

*Three panels are not needed here, with their repetition of axes, legend and text. 

*A legend is always curse as well as blessing, obliging the reader to go "back and forth" mentally (or memorise the legend, not something that appeals, however easy it might be). Informative text right by the bars is easier to follow. 

*The fruit salad colour coding is dispensable. It seems arbitrary too: "substantial" improvement is a big deal, but I find even strong yellow a subdued colour. But we don't need colour when we have text to explain. 

*Although some will shriek with horror at violating the distinction between Figure and Table, we can show the frequencies too. It's helpful to be able to think "4 people in this category". 

*There is homage here to the traditional plotting of response on the vertical axis, just as in the original. 
All that said, it is hard to see much structure in these data. When that's so, it is also hard to share the blame between (a) data without much structure and (b) the weaknesses of a graphical design for picking out not only predictor effects but also possible interactions. Treatment seems less important than baseline condition. But then, if the baseline was "mild", how much scope was there for "substantial" improvement? I'll stop there to stop making a fool of myself when the study of mental health data is certainly not a specialism, especially if the data turn out to be fake. But if they are real, we could do with a much larger sample size. (We usually say that, but there you go.) 
EDIT The graph may naturally be complicated by an ordinal colour scheme if so desired: 

For the record: the graphs used Stata code, including my own program tabplot downloadable using ssc inst tabplot. 
tabplot improvement group [w=frequency] , showval ///
xmla(1.5 "mild" 3.5 "moderate" 5.5 "severe", noticks labgap(*4) labsize(medsmall)) ///
xla(1 "0" 2 "1" 3 "0" 4 "1" 5 "0" 6 "1") ///
xtitle(baseline and treatment) xsc(titlegap(*4)) bfcolor(emerald*0.2)

tabplot improvement group [w=frequency] , showval ///
xmla(1.5 "mild" 3.5 "moderate" 5.5 "severe", noticks labgap(*4) labsize(medsmall)) ///
xla(1 "0" 2 "1" 3 "0" 4 "1" 5 "0" 6 "1") ///
xtitle(baseline and treatment) xsc(titlegap(*2)) ///
sep(improvement2) bar3(bfcolor(emerald*0.2)) bar2(bfcolor(emerald*0.6)) ///
bar1(bfcolor(emerald)) barall(blcolor(green)) 

A: Similar to parallel sets, as posted by nazareno above, you can use alluvial plots which are available from the alluvial R package. http://www.r-bloggers.com/alluvial-diagrams/
