Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

st: RE: RE: How to overlay multiple twoway bar graphs?

From   Nick Cox <>
To   "''" <>
Subject   st: RE: RE: How to overlay multiple twoway bar graphs?
Date   Wed, 5 Oct 2011 18:48:45 +0100

This is rather intricate code; I couldn't visualize the effect just by reading it. Could you supply a self-contained example with a posted dataset or one provided with Stata? I tried using your sample data and just got a very puzzling graph, I guess because your design was evidently for a much larger dataset. 

I'm left with a gut feeling that this is one of those cases where -graph bar, over()- might actually be a lot easier. I've often stressed that you may have to abandon -graph bar- and go for the greater flexibility of -twoway bar-, but the opposite can also be true. 

Also, did you check out -catplot- (SSC)? 


McDermaid, Cameron

Stata/SE 12.0 for Windows (32-bit)
Revision 15 Sep 2011

The problem: How to generate a bar graph by values in a categorical variable to get a product similar to --twoway bar count date, by(category)-- but with all plots in a single graph rather than a graph per categorical value?  The x axis data are dates, y axis counts by day. 

The solution: This solution uses macros to pass graph rbar statements by category value. It works as expected in the scenarios I've tried so I hope it's helpful to others.

Limitations: You need to know the maximum number of possible category values
The script also makes use of Nick Cox's floor/ceiling script  The Stata Journal (2003) 3, Number 4, pp. 446-447

Data format is agent of disease(category); date; count of cases by agent by day. There are no multiples of the same category by day.
category   day  	count
1   	  04sep2011   3
2	  04sep2011   4
3	  04sep2011   1
2       05sep2011   2
3	  05sep2011   5
1	  07sep2011   3
4       07sept2011  1


label define agent 1 "Unknown" 2 "Influenza A" 3 "Influenza B" 4 "Influenza A & B"  
label values category agent

* Predefine bar colors - maintains colour by agent for comparison between graphs
local color1 fcolor(yellow)    /* Unknown */
local color2 fcolor(blue)	/* Influenza A */
local color3 fcolor(green)	/* Influenza B */
local color4 fcolor(red)		/* Influenza A & B */

gen start=. /* Generate start & end points for rbar */
gen end=.
levelsof date, local(date)
foreach day of loc date {
	local start=0
	levelsof category if date==`day', local(agents)
	foreach lev of loc agents {
		replace start=`start' if date==`day' & category==`lev'
		replace end=`start'+count if date==`day' & category==`lev'
		sum end if date==`day' & category==`lev' 
		local start=`r(max)'

bysort date: gen total=_N  /* Generate yaxis scale using Nick Cox's ceiling script */
sum total
local ymax=10*ceil(`r(max)'/10)
drop total

local i=0  /* Generate plot macros by agent */
levelsof category, local(agents)  
foreach lev of loc agents {
local i=`i'+1
local name: label agent `lev'
local agent`i' rbar start end date if category==`lev', barwidth(0.8) `color`lev'' legend(lab (`i' `"`name'"'))||     

* Graph using macro statements: use as many macro statements as you have potential agents
twoway `agent1' `agent2' `agent3' `agent4' , title("Daily case counts by day") ylabel(0(5)`ymax') ytitle("Count") xtitle("Date") 
drop start end

McDermaid, Cameron
> Sent: September 15, 2011 8:49 AM
> I want to graph duration of disease outbreaks against the date of
> occurrence by aetiological agent for multiple sites so each site will
> have its own summary graph.  I've been trying to generate bar graphs
> such that duration is on the y-axis, date of onset along the x-axis and
> each aetiological agent represented by it's own bar colour.
> I can get the result I want by manually using || to overlay bar graphs
> where each additional plot represents the duration and onset date of a
> particular aetiological agent.
> e.g.
> twoway bar duration index_date if site==2 & aetiologicagent=1 ||
> duration index_date if site==2 & aetiologicagent=4
> However, I'd like to script this. I have 24 sites and not all sites had
> outbreaks with the same aetiological agents and, over time, the within-
> site agents may change depending on the time period. That's a lot of
> recoding if I take a manual approach to write disease specific graphs.
>  What I'd like to do is essentially overlays the graphs generated by:
> .twoway bar duration index_date if site==2, by(aetiologicagent)
> into one graph. I would loop through the instances of the sites to get
> summary graphs for each.
> I've tried a number of things without achieving the results I wanted.
> The only thing I haven't tried is to generate binary dummy variables for
> each aetiologic agent and include them all in a graph statement as
> overlays using ||. I'd expect the instances of aetiological agents that
> don't exist for that institution would not be plotted.
> Any suggestions of alternative solutions?

*   For searches and help try:

© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index