Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Change label of bar graph by two variables

    Hello everyone,

    I need to produce some graphs and I would like to add the total n by two categories to the labels. As you can see on the picture I attached, there are two variables on the yaxis (region and year). The number in parenthesis is the total n for each region but the thing is that I want it to be for each year different, not just for each region different. For example, in 2022 there were 100 cars in region A and 120 cars in region B.
    Is there a way to edit the labels of region by year? I used the following code:

    Code:
    graph hbar (count), over(car_class) over(region, relabel(1 `" "A" "(174 cars)" "' 2 `" "B" "(144 cars)" "')) over(year) percent stack asyvars ///
        ytitle("Percent") ///
        bar(1, fcolor(orange_red*.9) lw(none)) ///
        bar(2, fcolor(orange) lw(none)) ///
        bar(3, fcolor(yellow) lw(none)) ///
        bar(4, fcolor(green) lw(none)) ///    
        bar(5, fcolor(blue*.3) lw(none)) ///    
        blabel(bar, format(%4.0f) size(medium) position(center)) ///
        title("AAABBBB")
    Click image for larger version

Name:	Graph1.png
Views:	1
Size:	36.2 KB
ID:	1748753

  • #2
    Could you post the data as produced by

    Code:
    preserve 
    
    contract car_class region year 
    
    dataex 
    
    restore
    ?

    Comment


    • #3
      Hi Nick,

      Since the dataset is confidential, you can use the following code to produce a fake one and then the graph. I hope that helps.

      Code:
      clear
      
      set obs 300
      gen car_id = _n
      gen car_class = .
      gen region = .
      gen year = .
      
      replace car_class = runiformint(1, 5)
      replace year = runiformint(2021, 2023)
      replace region = runiformint(1, 2)
      
      label define car_class_lbl 1 "Economy/Compact Cars" 2 "Midsize Cars" 3 "Full-size Cars" 4 "Luxury Cars" 5 "Sports/Performance Cars"
      label define region_lbl 1 "A" 2 "B"
      
      label values car_class car_class_lbl
      label values region region_lbl
      
      graph hbar (count), over(car_class) over(region, relabel(1 `" "A" "(174 cars)" "' 2 `" "B" "(144 cars)" "')) over(year) percent stack asyvars ///
          ytitle("Percent") ///
          bar(1, fcolor(orange_red*.9) lw(none)) ///
          bar(2, fcolor(orange) lw(none)) ///
          bar(3, fcolor(yellow) lw(none)) ///
          bar(4, fcolor(green) lw(none)) ///    
          bar(5, fcolor(blue*.3) lw(none)) ///    
          blabel(bar, format(%4.0f) size(medium) position(center)) ///
          title("AAABBBB")

      Comment


      • #4
        You can directly change the values in the graph editor with graph. If you produce a lot of these graphs, you will need to know the y-axis positions and then use the undocumented gr_edit command after graphing. These positional values are displayed once you open the graph editor.


        Code:
        clear
        
        set obs 300
        gen car_id = _n
        gen car_class = .
        gen region = .
        gen year = .
        
        replace car_class = runiformint(1, 5)
        replace year = runiformint(2021, 2023)
        replace region = runiformint(1, 2)
        
        label define car_class_lbl 1 "Economy/Compact Cars" 2 "Midsize Cars" 3 "Full-size Cars" 4 "Luxury Cars" 5 "Sports/Performance Cars"
        label define region_lbl 1 "A" 2 "B"
        
        label values car_class car_class_lbl
        label values region region_lbl
        
        graph hbar (count), over(car_class) over(region) over(year) percent stack asyvars ///
            ytitle("Percent") ///
            bar(1, fcolor(orange_red*.9) lw(none)) ///
            bar(2, fcolor(orange) lw(none)) ///
            bar(3, fcolor(yellow) lw(none)) ///
            bar(4, fcolor(green) lw(none)) ///    
            bar(5, fcolor(blue*.3) lw(none)) ///    
            blabel(bar, format(%4.0f) size(medium) position(center)) ///
            title("AAABBBB")
        
        
        local y 5.64 19.09 43.27 56.72 80.9 94.35
        local totals 18 19 15 22 13 16
        forval i=1/6{
            local which= cond(mod(`i',2), "B", "A")
            gr_edit .grpaxis.edit_tick `i' `=word("`y'", `i')' `" "`which'" "({it:n=}`=word("`totals'", `i')' cars)" "', tickset(major)
        }
        Click image for larger version

Name:	Graph.png
Views:	1
Size:	69.3 KB
ID:	1748783

        Last edited by Andrew Musau; 03 Apr 2024, 13:04.

        Comment


        • #5
          Andrew Musau Thank you so much! It works! Just one more question. Where can I find the y-axis positions in the graph editor? I do not see them.

          Comment


          • #6
            From your first code that had the -relabel()- option, click on Start Graph Editor \(\rightarrow\) [Double click on the labels themselves]\(\rightarrow\) and finally click on "Edit or add individual ticks or labels" button.

            Comment


            • #7
              I am not really clear on the ultimate goal here, but I offer some technique using tabplot from the Stata Journal that may be of use or interest. The original graph seems to imply that some calls have very few or even zero observations. That is exactly what is implicit in a stacked bar chart but hard to read off, but conversely shows up more obviously on a two- or three-way bar chart as a small bar or even a hole in the display.

              Code:
              clear
              
              set seed 2803 
              set obs 300
              gen car_id = _n
              gen car_class = runiformint(1, 5)
              gen region = runiformint(1, 2)
              gen year = runiformint(2021, 2023) 
              
              label define car_class_lbl 1 "Economy/Compact Cars" 2 "Midsize Cars" 3 "Full-size Cars" 4 "Luxury Cars" 5 "Sports/Performance Cars"
              label define region_lbl 1 "A" 2 "B"
              
              label values car_class car_class_lbl
              label values region region_lbl
              
              bysort year region car_class : gen freq = _N
              bysort year region : gen total = _N 
              gen text = "{it:n} = " + strofreal(freq) + " (" + strofreal(100 * freq/total, "%2.0f") + "%)" 
              
              tabplot car_class region, by(year, row(1) note("") title("AAABBBB")) separate(car_class) percent(region year)  ///
                  bar1(fcolor(orange_red*.9) ) ///
                  bar2(fcolor(orange) ) ///
                  bar3(fcolor(yellow) ) ///
                  bar4(fcolor(green) ) ///    
                  bar5(fcolor(blue*.3) ) ///    
                  showval(text) ytitle("")
              Click image for larger version

Name:	cars_region_year.png
Views:	1
Size:	56.3 KB
ID:	1748801

              Comment

              Working...
              X