Announcement

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

  • Color modification of bar chart (twoway bar)

    Dear all,

    I would greatly appreciate your input on how to modify a simple bar chart.
    Specifically, I have sorted 774 patients by their individual scores on a symptom scale ("IPSS") from non (0) to severly symptomatic (35). Now I would like to color code patients by their symptom burden (IPSS values 0-7 in green; 8-19 in orange; 20-35 in red). Using the graph editor did not help; would anyone know how to code this ? Please see the current graph attached; the first 97 patients have a score of 0, therefore it appears as if there would be a blank.

    code:
    twoway bar postopipss ipssseq, barw(0.6)

    postopipss=IPSS score
    ipssseq=patients sorted by IPSS score

    Click image for larger version

Name:	Screen Shot 2022-01-10 at 21.38.21.png
Views:	1
Size:	224.6 KB
ID:	1644540


  • #2
    May I see the dataset (using dataex) used to make said bar chart?

    Comment


    • #3
      I'd recommend against a bar chart here, if only because (not only because) plotting 97 people implicitly as bars of zero height is just too much to explain (by you) and too puzzling (to readers).

      You want, I suggest, a version of what's most often called (in my reading) a quantile plot, although exactly what you want is beyond the official command quantile and even qplot from the Stata Journal.

      Still, that would just be a scatter plot. Here as a matter of convenience I used sepscatter from SSC. https://www.statalist.org/forums/for...lable-from-ssc

      Code:
      clear
      set obs 774
      gen IPSS = 0 in 1/97
      replace IPSS = ceil(35 * runiform()^2) in 98/L
      gen level = cond(IPSS <= 7, 1, cond(IPSS <= 19, 2, 3))
      label def level 1 "0-7" 2 "8-19" 3 "20-35"
      label val level level
      sort IPSS
      gen sequence = _n
      set scheme s1color
      sepscatter IPSS seq, separate(level) mc(black orange blue) yla(0(5)35, ang(h)) legend(ring(0) pos(11) row(1))
      
      sepscatter IPSS seq, separate(level) mc(black orange blue) yla(0(5)35, ang(h)) legend(ring(0) pos(11) row(1)) recast(bar)
      Click image for larger version

Name:	sepscatter2.png
Views:	1
Size:	19.6 KB
ID:	1644558



      I subverted the green orange red combination. Difficulty with red and green is common enough to avoid the combination (traffic lights notwithstanding).

      The last command above gives a bar chart version of the scatter plot.

      Code:
      histogram IPSS, discrete
      also works quite well.

      Comment


      • #4
        Hi Nick and Jared,

        thank you very much for the swift reply and help - this looks very good, example attached (I´ve also marked the median IPSS of the cohort).

        @Jared: I´m sorta hesitant to hesitant to use dataex here, as these are patient data. Attached is a screenshot of the dataset used.
        @Nick: If I may I´d like to ask your opinion the plot. Specifically, I´d like to increase the space between each plotted value on the x-axis, in order make the individual values (patients) visible. Changing the proportion of the x-axis or size of the symbols didn´t help. Any idea?

        Click image for larger version

Name:	Screen Shot 2022-01-12 at 11.34.08.png
Views:	1
Size:	112.6 KB
ID:	1644748
        Click image for larger version

Name:	Screen Shot 2022-01-12 at 11.53.18.png
Views:	2
Size:	127.4 KB
ID:	1644750
        Attached Files

        Comment


        • #5
          That median looks wrong to me unless I am misunderstanding your data.

          You're asking the impossible, I fear. Even with ms(p p p) the points will only be distinct if and only if just one patient has a particular score. I don't usually advocate histograms rather than quantile plots but I suspect they work better here, and are compatible with your binning.


          Code:
          clear
          set obs 774
          set seed 280352
          gen IPSS = 0 in 1/97
          replace IPSS = ceil(35 * runiform()^2) in 98/L
          gen level = cond(IPSS <= 7, 1, cond(IPSS <= 19, 2, 3))
          label def level 1 "0-7" 2 "8-19" 3 "20-35"
          label val level level
          sort IPSS
          gen sequence = _n
          set scheme s1color
          twoway histogram IPSS if level == 1, discrete freq bfc(black*0.2) blc(black) || ///
          histogram IPSS if level == 2, discrete freq bfc(orange*0.2) blc(orange) || ///
          histogram IPSS if level == 3, discrete freq bfc(blue*0.2) blc(blue) xla(0(5)35, ang(h)) ///
          legend(order(1 "0-7" 2 "8-19" 3 "20-35") ring(0) pos(1) row(1)) yla(, ang(h))
          Click image for larger version

Name:	gild.png
Views:	1
Size:	15.6 KB
ID:	1644752

          Comment


          • #6
            Hi,

            thanks againg for the quick help. Final graph (now with median) attached and as I wanted it to be.

            Click image for larger version

Name:	Screen Shot 2022-01-13 at 11.20.34.png
Views:	1
Size:	113.6 KB
ID:	1644920

            Comment

            Working...
            X