Announcement

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

  • Twoway graph with one legend in common

    Dear all, I would need your support for a small problem with a graph to be fixed.

    I have a series of graphs combined by means of -twoway-, and I would like to obtain just one legend in common at the end.

    Here the data:
    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input byte origin float pr byte dest float lab
    1 -.0020876 1  1
    2 -.1106231 1  2
    3 -.1982656 1  3
    4  -.254306 1  4
    1  -.026527 2  5
    2  .1525901 2  6
    3   -.08564 2  7
    4 -.0716028 2  8
    1  .0419532 3  9
    2  -.006786 3 10
    end
    label values origin origin
    label def origin 1 `""Ser/""WhC""', modify
    label def origin 2 "PB", modify
    label def origin 3 `""St.""WC""', modify
    label def origin 4 `""Unst.""WC""', modify
    label values dest dest
    label def dest 1 "DEST: Ser/WhC", modify
    label def dest 2 "DEST: PB", modify
    label def dest 3 "DEST: St WC", modify
    label values lab lab
    label def lab 1 ".00", modify
    label def lab 2 "-.11***", modify
    label def lab 3 "-.20***", modify
    label def lab 4 "-.25***", modify
    label def lab 5 "-.03***", modify
    label def lab 6 ".15***", modify
    label def lab 7 "-.09***", modify
    label def lab 8 "-.07***", modify
    label def lab 9 ".04***", modify
    label def lab 10 "-.01", modify
    Here the code:
    Code:
    tw(bar pr origin if lab ==  1, ) (scatter   pr origin  if lab ==  1, mlabel(lab)  mlabangle(45) mlabposition(12) mlabgap(6) mlabsize(vsmall) msymbol(i))   ///
     (bar pr origin if lab ==  2, ) (scatter   pr origin if lab == 2, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i)  )  ///
      (bar pr origin if lab ==  3, )  (scatter   pr origin if lab == 3, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  4, ) (scatter   pr origin if lab == 4, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
     (bar pr origin if lab ==  5, )  (scatter   pr origin if lab == 5, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  6, )  (scatter   pr origin if lab == 6, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
     (bar pr origin if lab ==  7, ) (scatter   pr origin if lab == 7, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
     (bar pr origin if lab ==  8, )  (scatter   pr origin if lab == 8, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  9, )  (scatter   pr origin if lab == 9, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  10, )  (scatter   pr origin if lab == 10, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  11, )  (scatter   pr origin if lab == 11, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  12, ) (scatter   pr origin if lab == 12, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
     (bar pr origin if lab ==  13, )  (scatter   pr origin if lab == 13, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  14, )  (scatter   pr origin if lab == 14, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  15, )  (scatter   pr origin if lab == 15, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  16, )  (scatter   pr origin if lab == 16, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
     (bar pr origin if lab ==  17, ) (scatter   pr origin if lab == 17, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  18, )  (scatter   pr origin if lab == 18, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     (bar pr origin if lab ==  19, )  (scatter   pr origin if lab == 19, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
     (bar pr origin if lab ==  20, ) (scatter   pr origin if lab == 20, mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
     , by(dest,  col(5))  ///
    scheme(s1mono) ///
    xlabel(1(1)4, valuelabel) ///
    ylabel(-.4(.1).4) ///
    yline(0, lc(red))
    I am playing around since a lot with -legend off- options and so on, but without any success.

    Do you any helpful clue? Would be very appreciated.

    Thanks, G

  • #2
    This is the graph I get with your data and your code. There is a mismatch in that your legend wants to show 20 elements but you have fewer in your example data, but having the whole dataset would not make any difference: this design does not work.


    Click image for larger version

Name:	giorgio.png
Views:	1
Size:	27.7 KB
ID:	1521418


    I see here pairs of origin and destination and a desire to show pr (whatever that is) and lab (ditto). With some small changes to your data I get this with tabplot (SSC/Stata Journal)


    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input byte origin float pr byte dest float lab
    1 -.0020876 1  1
    2 -.1106231 1  2
    3 -.1982656 1  3
    4  -.254306 1  4
    1  -.026527 2  5
    2  .1525901 2  6
    3   -.08564 2  7
    4 -.0716028 2  8
    1  .0419532 3  9
    2  -.006786 3 10
    end
    label values origin origin
    label def origin 1 "Ser/WhC", modify
    label def origin 2 "PB", modify
    label def origin 3 "St. WC", modify
    label def origin 4 "Unst. WC", modify
    label values dest dest
    label def dest 1 "Ser/WhC", modify
    label def dest 2 "PB", modify
    label def dest 3 "St WC", modify
    label values lab lab
    label def lab 1 ".00", modify
    label def lab 2 "-.11***", modify
    label def lab 3 "-.20***", modify
    label def lab 4 "-.25***", modify
    label def lab 5 "-.03***", modify
    label def lab 6 ".15***", modify
    label def lab 7 "-.09***", modify
    label def lab 8 "-.07***", modify
    label def lab 9 ".04***", modify
    label def lab 10 "-.01", modify
    
    decode lab, gen(label) 
    label var dest "destination" 
    
    tabplot origin dest [iw=pr] , showval(label) bfcolor(blue*0.3) blcolor(blue)

    The graph still needs a lot of work: Explain the variables. Expand the cryptic value labels. Would origin be better horizontal? The bars show pr and the text shows the labels, which may be trying too much. etc.

    Click image for larger version

Name:	giorgio2.png
Views:	1
Size:	18.8 KB
ID:	1521419

    Comment


    • #3
      You have a 'by' option in effect. To make the "legend off" completely, put the "legend off" option inside the 'by' option.
      Code:
       , by(dest, col(5) legend(off))
      Click image for larger version

Name:	test.png
Views:	1
Size:	102.1 KB
ID:	1521426
      Last edited by Roman Mostazir; 22 Oct 2019, 05:26. Reason: added the graph
      Roman

      Comment


      • #4
        Dear Nick, thanks a lot for your answer. I did some attempts with coefplot (I used it several times and I've found very useful), but in this case I do not like the way it shows the 'story'. Indeed, I would like to obtain a graph in which all the bars start from the same X axis (as the one that I obtain, which is the same you just posted, if you go to editor and hide the legend).

        The only think I would like to change with respect to it is to obtain just one legend instead of 20 and more (as you correctly pointed out).

        Don't you think it is something doable?

        Thanks for your kindness. G

        Comment


        • #5
          Dear Roman,

          yes, but actually I would need just one legend (not any at all), that's is the point I am struggling with.

          Comment


          • #6
            #4 Sorry, but I have no idea how coefplot (SSC, Stata Journal, as you are asked to explain: FAQ Advice #12) enters here, not least because I have no idea where what you want to plot comes from. Out of some model, no doubt, but we can't see that. Certainly it has nothing to do with my answer, as I didn't use it.

            As my design in #2 reduces the legend entries from 20 to 0 I don't understand that question either. You don't need a legend at all!

            A single x axis is certainly possible. Here is one example. The graph for the labels is really just the same.

            Code:
            * Example generated by -dataex-. To install: ssc install dataex
            clear
            input byte origin float pr byte dest float lab
            1 -.0020876 1  1
            2 -.1106231 1  2
            3 -.1982656 1  3
            4  -.254306 1  4
            1  -.026527 2  5
            2  .1525901 2  6
            3   -.08564 2  7
            4 -.0716028 2  8
            1  .0419532 3  9
            2  -.006786 3 10
            end
            label values origin origin
            label def origin 1 "Ser/WhC", modify
            label def origin 2 "PB", modify
            label def origin 3 "St. WC", modify
            label def origin 4 "Unst. WC", modify
            label values dest dest
            label def dest 1 "Ser/WhC", modify
            label def dest 2 "PB", modify
            label def dest 3 "St WC", modify
            label values lab lab
            label def lab 1 ".00", modify
            label def lab 2 "-.11***", modify
            label def lab 3 "-.20***", modify
            label def lab 4 "-.25***", modify
            label def lab 5 "-.03***", modify
            label def lab 6 ".15***", modify
            label def lab 7 "-.09***", modify
            label def lab 8 "-.07***", modify
            label def lab 9 ".04***", modify
            label def lab 10 "-.01", modify
            
            decode lab, gen(label) 
            destring label, ignore("*") replace 
            label var dest "destination" 
            
            graph hbar (asis) pr, over(origin) over(dest) name(G2, replace) title(pr)
            Code:
            
            


            Click image for larger version

Name:	giorgio3.png
Views:	1
Size:	22.0 KB
ID:	1521434



            Comment


            • #7
              Dear Nick,

              sorry for the mistake, I was referring to tabplot and not coeffplot, sorry about that.

              With respect to the my question on legend, sorry if I was not clear, what I was trying to say is that it would have been fine for me to obtain a graph like my (horrible) first with just one commond legend (while for each graph combined under -tw- I was obtaining a new legend, right?).

              Anyway thanks a lot for your inputs, I'll work on what you suggested to make my graph readable.

              Thanks again, G

              Comment


              • #8
                As you're asking, I don't see that a legend with 10 entries would have saved your design.

                Your intent was to show origin and destination by and within graph panels. Fine, but then minutely different shades of grey don't help in any way that I can imagine.

                This will sound harsh, but you asked for my opinion.

                Naomi Robbins wrote somewhere: Would you colour the words of a sentence in different colours? My answer: Only if you are a small child playing or an artist. Likewise if bars are labelled clearly, separate colours for every bar are just noise.
                Last edited by Nick Cox; 22 Oct 2019, 06:41.

                Comment


                • #9
                  #5, Here is another way using 'grc1leg'.

                  Code:
                  forval i=1/3 {
                  tw(bar pr origin if lab ==  1, ) (scatter   pr origin  if lab ==  1 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(12) mlabgap(6) mlabsize(vsmall) msymbol(i))   ///
                   (bar pr origin if lab ==  2, ) (scatter   pr origin if lab == 2& dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i)  )  ///
                    (bar pr origin if lab ==  3, )  (scatter   pr origin if lab == 3 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  4, ) (scatter   pr origin if lab == 4 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
                   (bar pr origin if lab ==  5, )  (scatter   pr origin if lab == 5 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  6, )  (scatter   pr origin if lab == 6 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
                   (bar pr origin if lab ==  7, ) (scatter   pr origin if lab == 7 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
                   (bar pr origin if lab ==  8, )  (scatter   pr origin if lab == 8 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  9, )  (scatter   pr origin if lab == 9 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  10, )  (scatter   pr origin if lab == 10 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  11, )  (scatter   pr origin if lab == 11 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  12, ) (scatter   pr origin if lab == 12 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
                   (bar pr origin if lab ==  13, )  (scatter   pr origin if lab == 13 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  14, )  (scatter   pr origin if lab == 14 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  15, )  (scatter   pr origin if lab == 15 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  16, )  (scatter   pr origin if lab == 16 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
                   (bar pr origin if lab ==  17, ) (scatter   pr origin if lab == 17 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  18, )  (scatter   pr origin if lab == 18 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) )  ///
                   (bar pr origin if lab ==  19, )  (scatter   pr origin if lab == 19 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i))  ///
                   (bar pr origin if lab ==  20, ) (scatter   pr origin if lab == 20 & dest==`i', mlabel(lab)  mlabangle(45) mlabposition(6) mlabgap(3) mlabsize(vsmall) msymbol(i) ),  ///
                      xlabel(1(1)4, valuelabel) ///
                      ylabel(-.4(.1).4) ///
                      yline(0, lc(red)) scheme(s1mono)  ///
                      legend(order(1 "Ser/Whc" 2 "PB" 3 "ST.WC" 4 "UNST.WC") col(2))
                  
                  gr copy x`i', replace
                  
                  }
                  //Combine the graphs
                  grc1leg x1 x2 x3, col(3) graphregion(fcol(white) lcol(bloack) lw(medthick))
                  
                  gr export test.png, replace
                  Click image for larger version

Name:	test.png
Views:	1
Size:	101.2 KB
ID:	1521456
                  Roman

                  Comment


                  • #10
                    Dear Nick,

                    I totally agree with you, I did not want different colors for different bars since they are showing exactly the same (difference in origin\destination pr between two groups). I would have need, in my idea, all the bars of the same color and one legend stating what each bar was representing (something like a box of the same color of all the bars plotted stating: group1-group2 pr).

                    Probably I agree with you that this legend would be meaningless, and that I may explaining somewhere else (for instance in the title) what is represented by each bar.

                    Dear Roman, thanks a lot for your example, I did not succeed in using grc1leg in combination with tw. I will play around following what you suggested.

                    Thanks a lot to both of you.

                    Best G

                    Comment


                    • #11
                      Dear Nick, do you have idea on why using exactly what you did:
                      graph hbar (asis) pr, over(origin) over(dest) name(G2, replace) title(pr) on my code Stata says 'tipe mismatch'? Very weird apparently

                      Comment


                      • #12
                        No. The complete code I used is in #6. I can't see what is different on your computer. But you have just three variables there, so

                        Code:
                        describe pr origin dest
                        will tell you what Stata sees in your dataset. A "type mismatch" is when Stata expects numeric, but sees string, or vice versa.

                        Comment

                        Working...
                        X