Announcement

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

  • Marker labels overplotting in scatterplot


    I'm attaching a scatterplot describing committee votes on articles of impeachment against President Nixon in 1974. The Y axis is the number of articles each committee member voted for, and the Y axis is a measure of how conservative each committee member was. Each point is labeled with the committee member's last name.

    Some of the names overlap. What can I do about that? Can I modify the code to prevent overlap? Can I move the names in Stata's Graph Editor? When I open the Graph Editor it seems to me I can't select individual names, but maybe there's a way I'm not finding.

    Here's the code and the scatterplot, in both gph and png.
    Code:
    twoway  (scatter articles_sum std_nominate_dim1 if democrat & committee, mcolor(blue) msymbol(O) msize(medlarge) mlabel(last_name) mlabangle(vertical) mlabsize(small) mlabposition(7) mlabcolor(blue) mlabangle(60)) ///
    (scatter articles_sum std_nominate_dim1 if republican & committee, mcolor(red) msymbol(Oh) msize(medlarge) mlabel(last_name) mlabangle(60) mlabposition(1) mlabsize(small) mlabcolor(red)), ///
     title("Votes on 5 articles of impeachment") subtitle("US House Judiciary Committee, July 27-30, 1974") ///
     xtitle("Conservatism (DW-Nominate dimension 1, standardized)") ytitle("Number of Yea votes") ///
     xscale(range(-2 2)) ///
     legend(lab(1 "Democrats") lab(2 "Republicans"))
    Click image for larger version

Name:	Committee vote.png
Views:	2
Size:	152.2 KB
ID:	1782633
    Best,
    Paul
    Attached Files

  • #2
    Not much, I suppose, except for decreasing the label size to the point that some of the 'doubles' are positioned separately. I suggest try to decrease by 50% and start changing that upward or downward.
    http://publicationslist.org/eric.melse

    Comment


    • #3
      You can see if the advices in this post can be helpful:

      https://www.statalist.org/forums/for...in-scatterplot

      Comment


      • #4
        I too have doubts about whether this design can be improved much.

        In the absence of a data example (please see advice in FAQ Advice #12 on data examples), I tried faking something loosely similar.

        Code:
        sysuse auto, clear
        
        set seed 314159
        
        keep if runiform() < 25/74
        
        pca displacement length trunk turn weight
        
        predict pc1
        
        sort rep78 pc1
        
        separate pc1, by(foreign) veryshortlabel
        
        graph dot pc1?,  over(make, sort(pc1) label(labsize(vsmall))) ///
        marker(1, ms(Oh) msize(medlarge) mcolor(red)) ///
        marker(2, ms(+) mcolor(blue) msize(medlarge)) over(rep78) nofill ndots(0) ///
        legend(order(2 "Democrat" 1 "Republican") pos(12) row(1)) ///
        title("Votes on 5 articles of impeachment", size(medium)) ///
        subtitle("US House Judiciary Committee, July 27-30, 1974") ///
        b1title("Conservatism (DW-Nominate dimension 1, standardized)") l1title("Number of Yea votes")
        Click image for larger version

Name:	demorep.png
Views:	1
Size:	59.9 KB
ID:	1782650



        This isn't very satisfactory to me either. I switched off the dots because otherwise I only get reference lines for one subset. More crucially, if and as you care about politician names, getting those distinct and legible remains the main graphical issue to me.

        Ideas at https://journals.sagepub.com/doi/pdf...6867X241297949 may help if the names can be sacrificed.
        Last edited by Nick Cox; 27 Oct 2025, 05:18.

        Comment


        • #5
          Originally posted by Nick Cox View Post
          I switched off the dots because otherwise I only get reference lines for one subset.
          This appears to be caused by the -nofill- option. As a workaround, one could plot the full set of points last and make the corresponding markers invisible. The axis labels (names of representatives) could also be color-coded, although likely one needs to adjust part of this manually using the Graph Editor if using graph dot.

          Code:
          sysuse auto, clear
          
          set seed 314159
          
          keep if runiform() < 25/74
          
          pca displacement length trunk turn weight
          
          predict pc1
          
          sort rep78 pc1
          
          separate pc1, by(foreign) veryshortlabel
          
          graph dot pc1? pc1,  over(make, sort(pc1) label(labsize(vsmall))) ///
          marker(1, ms(Oh) msize(medlarge) mcolor(red)) ///
          marker(2, ms(+) mcolor(blue) msize(medlarge)) over(rep78) ///
          marker(3, mcolor(none)) nofill ///
          legend(order(2 "Democrat" 1 "Republican") pos(12) row(1)) ///
          title("Votes on 5 articles of impeachment", size(medium)) ///
          subtitle("US House Judiciary Committee, July 27-30, 1974") ///
          b1title("Conservatism (DW-Nominate dimension 1, standardized)") l1title("Number of Yea votes")

          Res.:

          Click image for larger version

Name:	Graph.png
Views:	1
Size:	95.0 KB
ID:	1782652


          Comment


          • #6
            Andrew Musau Excellent diagnosis and solution. I've found that dotted lines in graphs don't port well to other software so tend to go for

            Code:
            linetype(line) lines(lc(gs12) lw(vthin))
            so solid lines. but thin and pale. I can't show the graph at the moment given some local IT problems.

            Comment


            • #7
              The equivalent of R's ggrepel would be very welcome in Stata, as first (I believe) requested by David Flood in the Wishlist for Stata 18

              https://www.statalist.org/forums/for...26#post1708626

              Comment


              • #8
                Bert Lloyd The thread linked in #3 has some discussion, including a community-contributed routine..

                A fairly trite (personal) summary of both manual and automated adjustment is that they can help with minor collisions but can't perform miracles.

                #1 looks too far gone to me. Already text is at an angle, which usually a sign of a problem best solved otherwise.

                Comment


                • #9
                  Sorry for not posting the data earlier. Here it is.
                  Attached Files

                  Comment


                  • #10
                    I appreciate your creative alternative plots. I'm having trouble visualizing how they would look with my data, and I appreciate that's because I didn't post my data earlier.

                    It seems the suggestion involves spreading out the vertical axis so it represents a combination of name and votes?

                    Comment


                    • #11
                      Using dataex with just the observations and variables needed would have been enough.

                      Here is a translation with some further squeezes.

                      Code:
                      keep if committee
                      
                      clonevar pc1 = std_nominate_dim1
                      separate pc1, by(democrat)
                      
                      graph dot pc1? pc1, ysize(6) over(last_name, sort(pc1) label(labsize(tiny))) ///
                      marker(1, ms(Oh) msize(medium) mcolor(red)) ///
                      marker(2, ms(+) mcolor(blue) msize(medium)) over(articles_sum) ///
                      marker(3, mcolor(none)) nofill ysc(reverse) linetype(line) lines(lc(gs12) lw(vthin)) ///
                      legend(order(2 "Democrats" 1 "Republicans") pos(12) row(1)) ///
                      title("Votes on 5 articles of impeachment", size(medium)) ///
                      subtitle("US House Judiciary Committee, July 27-30, 1974", size(medsmall)) ///
                      b1title("Conservatism (DW-Nominate dimension 1, standardized)", size(medsmall)) l1title("Number of Yea votes", size(medsmall))
                      Click image for larger version

Name:	demrep3.png
Views:	1
Size:	42.8 KB
ID:	1782692

                      Comment


                      • #12
                        Very elegant, thank you. I never would have thought of this....

                        Comment


                        • #13
                          Cleveland dot charts (as they are quite often called to distinguish from (Wilkinson) dotplots, which are pointillist histograms) remain under-used in my view.

                          Cleveland deserves the credit for his energetic advocacy, but as usual the history is flawed. For example, similar displays were included in several editions of Snedecor's once famous text, only to be removed by Cochran after he took over the book.

                          Comment


                          • #14
                            If I were to quibble...the vertical axis goes right from 0 to 2, skipping over 1. Is there a way to insert a blank row showing that no one voted for exactly 1 article?
                            Also, is there a way to put a header, such as "Representative" at the top of the column giving the Representatives' names?

                            Comment


                            • #15
                              Don't confuse the teacher with the research assistant! Also, firing up that dataset is harder work than having a proper data example given directly without extra stuff to wade through.

                              This should help. There is an extra pseudo-observation witjh just the right values. That's delicate because a blank for the name is omitted as missing, but a space will work.

                              The text Represenative is not where you want but you can drag it there in the Graph Editor (and resize the text, etc.).

                              Code:
                              * Example generated by -dataex-. For more info, type help dataex
                              clear
                              input byte articles_sum float(std_nominate_dim1 democrat) str13 last_name
                              5 -1.0030972 1 "Brooks"     
                              3  -.6718698 1 "Donohue"    
                              5 -1.3223884 1 "Kastenmeier"
                              0   1.378159 0 "Latta"      
                              4   -1.08665 1 "Rodino"     
                              5  -1.576031 1 "Edwards"    
                              0  1.5363128 0 "Hutchinson" 
                              2   .9753151 0 "Mcclory"    
                              5 -1.7520888 1 "Conyers"    
                              4  -.7792948 1 "Hungate"    
                              0   .8977302 0 "Smith"      
                              4  -1.295532 1 "Waldie"     
                              4 -1.1105223 1 "Eilberg"    
                              0  1.1275007 0 "Mayne"      
                              2  .51875836 0 "Railsback"  
                              0   .6261835 0 "Sandman"    
                              0    1.28267 0 "Wiggins"    
                              0  1.7332587 0 "Dennis"     
                              2   .4202853 0 "Fish"       
                              2 -.22724926 1 "Flowers"    
                              3     .68288 0 "Hogan"      
                              2  .11591424 1 "Mann"       
                              4 -1.2119793 1 "Danielson"  
                              4 -1.0478576 1 "Drinan"     
                              5 -1.3223884 1 "Rangel"     
                              3   -1.08665 1 "Sarbanes"   
                              4  -1.268676 1 "Seiberling" 
                              2  1.2021013 0 "Butler"     
                              2   .5098063 0 "Cohen"      
                              2  1.0946763 0 "Froehlich"  
                              5 -1.2597238 1 "Holtzman"   
                              5 -1.3462608 1 "Jordan"     
                              0   1.375175 0 "Lott"       
                              0   .6530398 0 "Maraziti"   
                              5 -1.0239854 1 "Mezvinsky"  
                              0  1.5989774 0 "Moorhead"   
                              4 -.54355645 1 "Owens"      
                              3  -.7017101 1 "Thornton"   
                              end
                              
                              insobs 1 
                              
                              clonevar y = std_nominate_dim1
                              replace y = 0 in L 
                              replace democrat = 2 in L 
                              separate y, by(democrat)
                              
                              replace last_name = " " in L 
                              replace articles_sum = 1 in L 
                              
                              graph dot y? y, ysize(6) over(last_name, sort(pc1) label(labsize(tiny))) ///
                              marker(1, ms(Oh) msize(medium) mcolor(red)) ///
                              marker(2, ms(+) mcolor(blue) msize(medium)) over(articles_sum) ///
                              marker(3, mcolor(none)) marker(4, mcolor(none)) nofill ysc(reverse) linetype(line) lines(lc(gs12) lw(vthin)) ///
                              legend(order(2 "Democrats" 1 "Republicans") pos(12) row(1)) ///
                              title("Votes on 5 articles of impeachment", size(medium)) ///
                              subtitle("US House Judiciary Committee, July 27-30, 1974", size(medsmall)) ///
                              b1title("Conservatism (DW-Nominate dimension 1, standardized)", size(medsmall)) l1title("Number of Yea votes", size(medsmall)) ///
                              note(Representative, pos(11))
                              Click image for larger version

Name:	committee.png
Views:	1
Size:	85.5 KB
ID:	1782725


                              Comment

                              Working...
                              X