Announcement

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

  • Customize bars color with multiple over(.)

    Hi,

    I am new in the forum and I have an issue with a bar graph.

    This is my graph command :

    reshape long Mysk, i(Email) j(question)

    encode Mysk, gen(Mysk_reshaped)

    label define catlbl 1 "Very Appropriate" 2 "Appropriate" 3 "Somewhat Appropriate" ///
    4 "Somewhat Inappropriate" 5 "Inappropriate" 6 "Very Inappropriate"

    label values Mysk_reshaped catlbl

    graph bar (percent), over(question, gap(2) label(labsize(small)) relabel(1 "PN" 2 "SN" 3 "csPN")) over(Mysk_reshaped, gap(50) label(angle(45) labsize(small))) ascategory ytitle("Percent of respondents", size(small)) title("Distribution of responses by category", size(medsmall)) legend(order(1 "PN" 2 "SN" 3 "csPN") size(small) position(6)) bar(1, fcolor(blue) lcolor(black)) bar(2, fcolor(red) lcolor(black)) bar(3, fcolor(green) lcolor(black))

    The problem is that I would like the bars to have different color by "question", so the bar PN to be red (for example), the bar SN to be black and the bar csPN to be green. If I run that command however the result is the one attached: all bars are blue. I have tried to ask AI but I couldn't find a solution, so I am trying here if anyone could help me.

    Thank you very much in advance.
    best,
    Sarah

    Click image for larger version

Name:	Screenshot 2025-10-27 at 15.26.09.png
Views:	1
Size:	773.4 KB
ID:	1782660

  • #2
    I'm not a fan of angled categorical labels on the x-axis. If you're concerned that the labels won't be fully visible, a horizontal bar graph is a design that solves this problem. Regarding your specific question, you should replace the option -ascategory- with both -asyvars- and -showyvars-. You can then suppress the legend.

    Code:
    clear
    *SIMULATE DATASET
    set seed 10272025
    set obs 200
    gen Mysk_reshaped= runiformint(1,6)
    gen question= cond(_n<=40, 1, cond(inrange( _n, 41, 100),2, 3))
    
    label define catlbl 1 "Very Appropriate" 2 "Appropriate" 3 "Somewhat Appropriate" ///
    4 "Somewhat Inappropriate" 5 "Inappropriate" 6 "Very Inappropriate"
    
    label values Mysk_reshaped catlbl
    
    *GRAPH
    graph hbar (percent), over(question, gap(2) label(labsize(small)) ///
    relabel(1 "PN" 2 "SN" 3 "csPN")) over(Mysk_reshaped, gap(50) ///
    label( labsize(small))) asyvars showyvars ///
    ytitle("Percent of respondents", size(small)) ///
    title("Distribution of responses by category", size(medsmall)) ///
    legend(order(1 "PN" 2 "SN" 3 "csPN") size(small) position(6)) ///
    bar(1, fcolor(stc1) lcolor(black)) bar(2, fcolor(stc2) lcolor(black)) ///
    bar(3, fcolor(stc3) lcolor(black)) leg(off)
    Res.:

    Click image for larger version

Name:	Graph.png
Views:	1
Size:	33.9 KB
ID:	1782698

    Comment


    • #3
      Thank you very much Andrew: that was very useful!!

      Comment


      • #4
        Note that the percents in #2 are percents over the combination of questions and categories, so over all responses, not over each question. In Andrew Musau's fake data, the numbers of answers to the three questions were 40, 60, 100 (csPN), so on average csPN percents are higher, and so on. Check that the average percent across bars is visually similar to 100/18 which is about 5.56.

        If you want the percent of each category for each question, here is one way to do that. Note that you must install catplot for this particular solution to work.

        Code:
        clear
        *SIMULATE DATASET
        set seed 10272025
        set obs 200
        gen Mysk_reshaped= runiformint(1,6)
        gen question= cond(_n<=40, 1, cond(inrange( _n, 41, 100),2, 3))
        
        label define catlbl 1 "Very Appropriate" 2 "Appropriate" 3 "Somewhat Appropriate" ///
        4 "Somewhat Inappropriate" 5 "Inappropriate" 6 "Very Inappropriate"
        
        label values Mysk_reshaped catlbl
        
        ssc install catplot, replace 
        
        *GRAPH
        catplot, percent(question) over(question, gap(2) label(labsize(small)) ///
        relabel(1 "PN" 2 "SN" 3 "csPN")) over(Mysk_reshaped, gap(50) ///
        label( labsize(small))) asyvars showyvars ///
        ytitle("Percent by question", size(small)) ///
        title("Distribution of responses by category", size(medsmall)) ///
        legend(order(1 "PN" 2 "SN" 3 "csPN") size(small) position(6)) ///
        bar(1, fcolor(stc1) lcolor(black)) bar(2, fcolor(stc2) lcolor(black)) ///
        bar(3, fcolor(stc3) lcolor(black)) leg(off)
        Click image for larger version

Name:	catplot_new.png
Views:	1
Size:	47.8 KB
ID:	1782715

        Comment

        Working...
        X