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]

Re: st: Suppress labeling of categorical axis values in graph bar/hbar

From   Roger Newson <>
To   "" <>
Subject   Re: st: Suppress labeling of categorical axis values in graph bar/hbar
Date   Mon, 20 Dec 2010 17:28:06 +0000

This problem sounds like a possible job for -sencode-, which you can download from SSC. As in:

sencode make, gene(makeprice) gsort(price)

which will produce a new labelled numeric variable -makeprice-, whose numeric values vary from 1 to 74 in non-descending order of -price-, and whose corresponding labels are the string values of -make-. You can then input -makeprice- into -graph bar- or -graph twoway bar-, using the -xlabels()- option to label whatever subset of cars you want to label, if there is not enough room on the axis to label them all. To find outh which number has been allocated to which label, type

lab list nummake

which will list the numbers and their labels.

I hope this helps.

Best wishes


Roger B Newson BSc MSc DPhil
Lecturer in Medical Statistics
Respiratory Epidemiology and Public Health Group
National Heart and Lung Institute
Imperial College London
Royal Brompton Campus
Room 33, Emmanuel Kaye Building
1B Manresa Road
London SW3 6LR
Tel: +44 (0)20 7352 8121 ext 3381
Fax: +44 (0)20 7351 8322
Web page:
Departmental Web page:

Opinions expressed are those of the author, not of the institution.

On 20/12/2010 16:08, Nick Cox wrote:
There's an ancient Stata saying that if -graph bar- seems to block your path, back up and try an equivalent approach with -twoway bar-.

Your example can be attacked with

sysuse auto, clear
sort price
gen order = _n
labmask order, values(make)
twoway bar price order, horizontal yla(8 44 71, val ang(h)) ytitle("")

The mystery command here is -labmask-: see

SJ-8-2  gr0034  . . . . . . . . . .  Speaking Stata: Between tables and graphs
         (help labmask, seqvar if installed) . . . . . . . . . . . .  N. J. Cox
         Q2/08   SJ 8(2):269--289
         outlines techniques for producing table-like graphs

for more detail and, especially, more on the generic problem here. You don't need -labmask- to get what you want. A direct approach would be

sysuse auto, clear
sort price
gen order = _n
twoway bar price order, horizontal yla(8 "Renault Le Car" 44 "VW Diesel" 71 "Linc. Versailles", val ang(h)) ytitle("")

However, there are problems in which -labmask- cuts down mightily on what you have to type.

To get the correspondence 8 "Renault Le Car" etc. you have to look at the dataset after ordering.


Davide Cantoni

Eric -- thanks for your reply. It is somehow convincing me that I am
almost as well off by typing out the relabel() option manually.

The other thing I wonder is how to get rid of the numbers on the
categorical axis. In your second code, which works fine, there are
still the ordinal numbers of each observation, instead of the names,
left. There's no way to suppress those?

Eric Booth

I think that working with the relabel option is your best bet.  You can automate
  the creation of the  relabel() expression with a loop, but normally I'd suggest
  building it in a local macro , but I couldn't get the local to store the double
quotes for use in the relabel option.

Here's some examples of things I tried:

sysuse auto, clear
forval n = 1/`=_N' {
        loc la1 `la1' `"`n' " " "'
        loc la2 `la2' "`n' " " "
        loc la3 `la3' `n' `" "'
        loc la4 `"`la4' `n' " "'"'
forval n = 1/4 {
        di in y as smcl "`n' {hline}"
        di in g "`la`n''"
Anyone have an idea of how to store the double quotes  in a local to pass to the
relabel option?

Since using the local didn't work for me, here's a less straightforward solution
using a couple of string variables (which are limited to 244 chars) to do essentially
the same thing:

sysuse auto, clear

foreach v in "1/15" "16/30" "31/45" "46/60" "61/74" {
**get variable name**
loc varname `v'
loc varname: subinstr local varname `"/"' "", all

**create "o" vars with relabel option**
g o`varname' = ""
forval n = `v' {
if !inlist(`n', 1, 20, 40, 60 , 74)  ///
replace o`varname' = o`varname' + `" `n' " " "'
if inlist(`n', 1, 20, 40, 60 , 74)  ///
replace o`varname' = o`varname' + `" `n' "`=make[`n']' ""'

ds o* //<-- Here's the new vars for relabel()

graph hbar (asis) price, bargap(10)  ///
  over(make, relabel(`=o115' ///
  `=o1630'  `=o3145'  `=o4660'  `=o6174')  ///
  label(angle(horizontal) labsize(vsmall) labgap(5)))


After kludging all this together, it might be more work than typing out
  the relabel()  for 74 obs in the auto.dta;  however, it would be useful
for much  larger datasets.  (However,  you can't get too much larger
before  the bars become indistinguishable.)

Davide Cantoni

I would like to draw a bar chart displaying the values of a given
variable for all the observations in the dataset. However, since there
are many observations, I would like to label only some of them (some
representative cases). Conceptually, this is similar to this working

*** begin example
sysuse auto, clear
graph hbar (asis) price, over(make, sort(price))
*** end example

As you can see, putting all the labels on the categorical axis leads
to overcrowding. What I would like to do is to label only some
representative examples, e.g. only "Renault Le Car", "VW Diesel" and,
say, "Lincoln Versailles".  I guess I can achieve the suppression of
labels with some relabel() command inside the over() parenthesis, but
given the large number of observations, this would be incredibly
cumbersome. Any other suggestions?

*   For searches and help try:
*   For searches and help try:

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