Announcement

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

  • spineplot broken?

    spineplot is a package for Stata described in this Stata Journal article. It can be installed with
    Code:
    ssc install spineplot
    The help file includes this example:
    Code:
    sysuse auto
    spineplot foreign rep78, xti(frequency, axis(1)) xla(0(10)60, axis(1)) xmti(1/69, axis(1))
    When I run this command on my PC I get this graph:



    Could you please confirm if you get the same graph or if this is supposed to look different? The other examples from the help file produce graphs that look as I would expect. Here is another example:
    Code:
    spineplot foreign rep78


    I am asking because I noticed that some old code of mine that uses spineplot is now broken and produces graphs that look similar to the first graph above: the rectangle is empty and all labels on the lower axis have been pushed to the left side. Here is a graph that I created in 2016:



    Here is the graph that I get today with the same do-file and same dataset used to create the graph above:



    I tried Stata 13.1 and 14.2 with the same result. I even went back to spineplot 1.0.4, which I had used last year (the current version is 1.1.1), but the graph is still empty. The only reason I can think of is a recent update to Windows 10 version 1703 but it seems odd that this would have an effect on spineplot graphs. I have no problems with other Stata graph commands.

  • #2
    I identified the source of the problem and it has nothing to do with Windows. The way spineplot handles labels on the x-axis was changed from version 1.0.4 to version 1.1.1. The help file for the most recent version mentions a "revision in 2016 to improve handling of x axis labels".

    When I tested version 1.0.4 earlier, I neglected to restart Stata and therefore continued to use version 1.1.1. I have now installed version 1.0.4 correctly and it is able to generate a correct graph with this command from the help file:
    Code:
    sysuse auto
    spineplot foreign rep78, xti(frequency, axis(1)) xla(0(10)60, axis(1)) xmti(1/69, axis(1))
    Click image for larger version

Name:	test.png
Views:	1
Size:	13.9 KB
ID:	1393645


    With spineplot 1.1.1, the same command creates an empty graph, as you can see in the first graph in post #1: all bar segments have been compressed to an area between 0 and 1 on the x-axis.

    After I identified the source of the problem I modified the spineplot labels in my do-file and can now draw proper graphs with version 1.1.1.

    Comment


    • #3
      This isn't quite as puzzling as perhaps implied, although users and indeed the programmer, videlicet myself, have variously had to work at thinking straight on this.

      Although I understand the issues, I'll note that I can't read any of the graphs in #1.

      The 2016 fix arose as documented here: http://www.statalist.org/forums/foru...ot-axis-labels

      spineplot 1.1.1 is what I should have written in the first place. It's explained in the help that the plot shows fractional breakdown. The scales of both axes are fractional, showing cumulative probability and so vary from 0 to 1.

      It follows that trying also to show cumulative frequency on that scale without appropriate trickery is doomed unless trivially the cumulative frequency also varies from 0 to 1, i.e. there is only one observation! For the auto data and example given, the cumulative frequency ranges up to 69 and so even for a small dataset the clash can be some orders of magnitude.

      The original design attempted to give users the best of both worlds, by pretending to show fractions but actually using cumulative frequency in the graph command. That itself was confusing and Dimitriy Masterov flagged the problem.

      The point of the change is best shown by Friedrich's own example in #2.

      Code:
      sysuse auto, clear
      spineplot foreign rep78
      Suppose you want to change the bottom x axis labels. How do you it, other than using the Graph Editor? The specification is a saved result, so you can see it and make a second pass around.

      Code:
      ret li
      
      macros:
                r(catlabels) : "0.0145 "1"  0.0870 "2"  0.3623 "3"  0.7101 "4"  0.9203 "5""
      Now I can reissue the command with a different set of labels:


      Code:
      spineplot foreign rep78, xla(0.0145 "Abysmal" 0.0870 "Awful" 0.3623 "Average" 0.7101 "Amazing" 0.9203 "Awesome", axis(2) ang(v))
      The point is that you don't know the positions of the labels unless you do the calculation independently, or as here get the program to tell you what they are.

      What trickery is needed to show frequencies too? We need to map from (0, number of observations) to (0, 1). mylabels (SSC) is a helper command for that.

      Code:
      count if !missing(foreign, rep78)
      mylabels 0(10)60, myscale(@/69) local(wanted)
      
      spineplot foreign rep78, ///
      xla(0.0145 "Abysmal" 0.0870 "Awful" 0.3623 "Average" 0.7101 "Amazing" 0.9203 "Awesome", axis(2) ang(v)) ///
      xla(`wanted', axis(1)) xtitle(Frequency, axis(1))
      Anyone happier with the old version should avoid updating to the 2016 version!
      Last edited by Nick Cox; 19 May 2017, 05:46.

      Comment


      • #4
        Thank you for the explanation. With spineplot 1.0.4 I did the calculations for the label positions in the do-file. After the update to version 1.1.1 the labels were no longer placed correctly because they were remapped to values between 0 and 1.

        Sorry for the missing images. I can see them when I am logged in but they don't appear when I am logged out. I don't know what happened. For clarity, let me show again the first graph in post #1. I used spineplot 1.1.1 and an example from the help file.
        Code:
        sysuse auto
        spineplot foreign rep78, xti(frequency, axis(1)) xla(0(10)60, axis(1)) xmti(1/69, axis(1))
        Click image for larger version

Name:	spineplot.png
Views:	1
Size:	10.7 KB
ID:	1393757

        Version 1.0.4 yields the graph in post #2 with the same command. With version 1.1.1, everything is moved to the left side to fit between the values 0 and 1. To get the same graph as in post #2 with spineplot 1.1.1, the following commands can be used. Note that mylabels, mentioned by Nick, is also required.
        Code:
        count if !missing(foreign, rep78)
        mylabels 0(10)60, myscale(@/69) local(labels)
        myticks 0(1)69, myscale(@/69) local(ticks)
        spineplot foreign rep78, xla(`labels', axis(1)) xmti(`ticks', axis(1)) xtitle("frequency", axis(1))
        Click image for larger version

Name:	spineplot2.png
Views:	1
Size:	13.0 KB
ID:	1393758

        Comment

        Working...
        X