Announcement

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

  • Setting the colour of certain variables on bar graphs

    Hello,

    I am creating bar graphs to display the results of testing for several salmonella serovars. Thanks to Statalist for making my code automated and it can now be used on different datasets to produce the same graphs! However, I was wondering if it is possible to set certain salmonella serovars as a certain colour? Right now I have assigned each bar a certain colour manually but since the different datasets contain different serovars – the same serovar ends up as different colour. Is there away to assign a colour to a certain serovar in this case?
    This isn’t the end of the world problem but it would be nice to have consistency across the graphs from different datasets.

    Here is my code: * Example generated by -dataex-. For more info, type help dataex
    Code:
    clear
    input int year byte(negative anatum enteritidis hadar typhimurium)
    2010 20 1 1 2 0
    2011 18 2 1 2 3
    2012 36 4 0 2 3
    2013 29 0 1 0 4
    2014 23 2 0 1 2
    end
    
    ds year negative, not
    local vars=wordcount("`r(varlist)'")
    graph bar (asis) negative `r(varlist)', over(year, label(labsize(vsmall))) stack legend (size(vsmall)) legend(region(lstyle(none))) legend(cols(4) colgap(5.2) symxsize(9)) ylabel(,angle(horizontal) labsize(vsmall)) graphregion(color(white)) ytitle("Number of Samples", margin(medium)) blabel(bar,position(center) color(white)) bar(1,color(navy)) bar(2,color(maroon)) bar(3,color(red)) bar(4,color(purple)) bar(5,color(stone)) bar(6,color(lavender))
     
    levelsof year, local(years)
    local bars = wordcount("`years'")
    local exclude 1
    local count =`vars'+2
    forval bars =1/`bars'{
        local exclude "`exclude' , `count'"
        local count = `count' + `vars'+ 1
    }
    forval i=1/`.Graph.plotregion1.barlabels.arrnels' {
        if !inlist(`i', `exclude'){
            gr_edit .plotregion1.barlabels[`i'].text[1]=" "
        }
    }
    An example of how graph looks for dataset 1:

    Click image for larger version

Name:	Statalist colour post graph 1.png
Views:	1
Size:	43.9 KB
ID:	1618709


    And I can apply this code to a different data set as below, but of course I get different colours for my serovars because they have changed slightly:

    * Example generated by -dataex-. For more info, type help dataex
    Code:
    clear
    input int year byte(negative enteritidis infantis hadar seftenberg typhimurium)
    2010 23 4 1 2 1 2
    2011 26 5 0 2 1 3
    2012 29 3 0 4 3 4
    2013 33 2 1 2 1 2
    2014 24 4 1 4 3 1
    end
    
    ds year negative, not
    local vars=wordcount("`r(varlist)'")
    graph bar (asis) negative `r(varlist)', over(year, label(labsize(vsmall))) stack legend (size(vsmall)) legend(region(lstyle(none))) legend(cols(4) colgap(5.2) symxsize(9)) ylabel(,angle(horizontal) labsize(vsmall)) graphregion(color(white)) ytitle("Number of Samples", margin(medium)) blabel(bar,position(center) color(white)) bar(1,color(navy)) bar(2,color(maroon)) bar(3,color(red)) bar(4,color(purple)) bar(5,color(stone)) bar(6,color(lavender))
     
    levelsof year, local(years)
    local bars = wordcount("`years'")
    local exclude 1
    local count =`vars'+2
    forval bars =1/`bars'{
        local exclude "`exclude' , `count'"
        local count = `count' + `vars'+ 1
    }
    forval i=1/`.Graph.plotregion1.barlabels.arrnels' {
        if !inlist(`i', `exclude'){
            gr_edit .plotregion1.barlabels[`i'].text[1]=" "
        }
    }
    And graph for dataset 2 looks like:
    Click image for larger version

Name:	Statalist colour post graph 2.png
Views:	1
Size:	46.0 KB
ID:	1618710

    Curious to hear your thoughts - if this is at all possible? Thanks.

    Also, is "bar(#,colour)" the best way to assign colours in bar graph? If I let stata use it's normal colour scheme I noticed the colours start repeating in the legend after about 15 variables. This is not ideal when I have 20+ serovars for some of these graphs. I have also been looking at creating a custom colour scheme before I run the graph but I find there are minimal references to create your own colour scheme. I know this won't change the above problem but at least it would get rid of the repeating colours issue I am having. Thanks!

  • #2
    If you have the full list of serovars, you can always generate variables with all entries zero for the nonexistent serovars. This will not alter the number of samples displayed. However, the nonexistent serovars will be included in the legend. This can be fixed. Let me know if you want to exclude them.

    Code:
    clear
    input int year byte(negative anatum enteritidis hadar typhimurium)
    2010 20 1 1 2 0
    2011 18 2 1 2 3
    2012 36 4 0 2 3
    2013 29 0 1 0 4
    2014 23 2 0 1 2
    end
    
    foreach var in anatum enteritidis infantis hadar seftenberg typhimurium{
        cap gen `var'=0
    }
    order year negative anatum enteritidis infantis hadar seftenberg typhimurium
    
    ds year negative, not
    local vars=wordcount("`r(varlist)'")
    graph bar (asis) negative `r(varlist)', over(year, label(labsize(vsmall))) stack legend (size(vsmall)) legend(region(lstyle(none))) legend(cols(4) colgap(5.2) symxsize(9)) ylabel(,angle(horizontal) labsize(vsmall)) graphregion(color(white)) ytitle("Number of Samples", margin(medium)) blabel(bar,position(center) color(white)) bar(1,color(navy)) bar(2,color(maroon)) bar(3,color(red)) bar(4,color(purple)) bar(5,color(stone)) bar(6,color(lavender))
     
    levelsof year, local(years)
    local bars = wordcount("`years'")
    local exclude 1
    local count =`vars'+2
    forval bars =1/`bars'{
        local exclude "`exclude' , `count'"
        local count = `count' + `vars'+ 1
    }
    forval i=1/`.Graph.plotregion1.barlabels.arrnels' {
        if !inlist(`i', `exclude'){
            gr_edit .plotregion1.barlabels[`i'].text[1]=" "
        }
    }
    
    clear
    input int year byte(negative enteritidis infantis hadar seftenberg typhimurium)
    2010 23 4 1 2 1 2
    2011 26 5 0 2 1 3
    2012 29 3 0 4 3 4
    2013 33 2 1 2 1 2
    2014 24 4 1 4 3 1
    end
    
    foreach var in anatum enteritidis infantis hadar seftenberg typhimurium{
        cap gen `var'=0
    }
    order year negative anatum enteritidis infantis hadar seftenberg typhimurium
    ds year negative, not
    local vars=wordcount("`r(varlist)'")
    graph bar (asis) negative `r(varlist)', over(year, label(labsize(vsmall))) stack legend (size(vsmall)) legend(region(lstyle(none))) legend(cols(4) colgap(5.2) symxsize(9)) ylabel(,angle(horizontal) labsize(vsmall)) graphregion(color(white)) ytitle("Number of Samples", margin(medium)) blabel(bar,position(center) color(white)) bar(1,color(navy)) bar(2,color(maroon)) bar(3,color(red)) bar(4,color(purple)) bar(5,color(stone)) bar(6,color(lavender))
     
    levelsof year, local(years)
    local bars = wordcount("`years'")
    local exclude 1
    local count =`vars'+2
    forval bars =1/`bars'{
        local exclude "`exclude' , `count'"
        local count = `count' + `vars'+ 1
    }
    forval i=1/`.Graph.plotregion1.barlabels.arrnels' {
        if !inlist(`i', `exclude'){
            gr_edit .plotregion1.barlabels[`i'].text[1]=" "
        }
    }

    Click image for larger version

Name:	Graph.png
Views:	1
Size:	51.4 KB
ID:	1618724


    Click image for larger version

Name:	Graph2.png
Views:	1
Size:	52.7 KB
ID:	1618725

    Last edited by Andrew Musau; 13 Jul 2021, 14:30.

    Comment


    • #3
      Hello Andrew,

      Yes this might work. Can you please generate the legend without the non-existent serovars being displayed? Thanks!

      Comment


      • #4
        Code:
        clear
        input int year byte(negative enteritidis infantis hadar seftenberg typhimurium)
        2010 23 4 1 2 1 2
        2011 26 5 0 2 1 3
        2012 29 3 0 4 3 4
        2013 33 2 1 2 1 2
        2014 24 4 1 4 3 1
        end
        
        local legend 
        local count 2
        foreach var in anatum enteritidis infantis hadar seftenberg typhimurium{
            cap gen `var'=0
            if _rc{
                local legend "`legend' `count' `"`var'"'"
            }
            local ++count
        }
        order year negative anatum enteritidis infantis hadar seftenberg typhimurium
        ds year negative, not
        local vars=wordcount("`r(varlist)'")
        graph bar (asis) negative `r(varlist)', over(year, label(labsize(vsmall))) ///
        stack legend (size(vsmall)) legend(region(lstyle(none))) ///
        legend(order(1 "negative" `legend') cols(4) colgap(5.2) symxsize(9)) ///
        ylabel(,angle(horizontal) labsize(vsmall)) graphregion(color(white)) ///
        ytitle("Number of Samples", margin(medium)) blabel(bar,position(center) ///
        color(white)) bar(1,color(navy)) bar(2,color(maroon)) bar(3,color(red)) ///
        bar(4,color(purple)) bar(5,color(stone)) bar(6,color(lavender))
        
        levelsof year, local(years)
        local bars = wordcount("`years'")
        local exclude 1
        local count =`vars'+2
        forval bars =1/`bars'{
            local exclude "`exclude' , `count'"
            local count = `count' + `vars'+ 1
        }
        forval i=1/`.Graph.plotregion1.barlabels.arrnels' {
            if !inlist(`i', `exclude'){
                gr_edit .plotregion1.barlabels[`i'].text[1]=" "
            }
        }
        Some notes:

        1) Make sure that the serovars in the first -foreach- loop (highlighted in red) are complete and ordered. So as bar #1 is the negative category, bar#2 will correspond to the first variable in the list, bar#3 the second variable in the list and so on.

        2) When specifying colors (highlighted in the code), come up with a list of colors that includes the complete list of serovars. The point is that each serovar should be associated with a distinct color. So your codes should include bar(1, color(xxx)), bar(2, color(xxx)), ... , up to the last, e.g., bar(21, color(xxx)).


        Click image for larger version

Name:	Graph.png
Views:	1
Size:	47.9 KB
ID:	1619826

        Comment

        Working...
        X