Matplotlib: Histogram with bars inside grid lines...how??

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Enigma Curry

    #1

    Matplotlib: Histogram with bars inside grid lines...how??

    I'm playing around with matplotlib for the first time. I'm trying to
    make a very simple histogram of values 1-6 and how many times they
    occur in a sequence. However, after about an hour of searching I cannot
    make the histogram stay within the bounds of the grid lines.

    Here is my example:

    pylab.grid()
    x_values=[1,1,2,2,2,3,3,3 ,4,4,4,5,5,6,6, 6]
    pylab.hist(x_va lues,6)
    pylab.show()

    This produced the following image:


    Starting with bar number 2, it creeps into grid 1.. and finally with
    bar number 5 it's almost entirely in grid 4.. how do I make the bars
    stay in their own grid lines?

    I can see that hist() is somehow derived from bar() ... so it appears
    that hist() has some undocumented parameters. I tried specifiying
    width=1 but that just squished all of the bars together.

    Also, is there a more object-oriented graphing package for Python? (How
    am I supposed to know that hist() is derived from bar() if the docs
    don't show proper inheritance?)

    Thanks!

  • Enigma Curry

    #2
    Re: Matplotlib: Histogram with bars inside grid lines...how??

    Two things:

    1) I now see where width is defined in the hist() documentation.. . I
    was expecting it to be in the definition up at the top, but instead the
    definition has **kwords.. not very helpful.

    2) I noticed in my original historgram, that the y scale was not the
    same as the x scale.. so I updated my code:

    import pylab

    pylab.grid()
    x_values=[1,1,2,2,2,3,3,3 ,4,4,4,5,5,6,6, 6]
    pylab.hist(x_va lues,6)
    pylab.yticks(py lab.arange(3))
    pylab.axis('sca led')
    pylab.show()


    It produced this image:


    It has the same problem..

    Comment

    • John Hunter

      #3
      Re: Matplotlib: Histogram with bars inside grid lines...how??

      >>>>> "Enigma" == Enigma Curry <workbee@gmail. com> writes:

      Enigma> I'm playing around with matplotlib for the first time. I'm
      Enigma> trying to make a very simple histogram of values 1-6 and
      Enigma> how many times they occur in a sequence. However, after
      Enigma> about an hour of searching I cannot make the histogram
      Enigma> stay within the bounds of the grid lines.

      Enigma> Here is my example:

      Enigma> pylab.grid() x_values=[1,1,2,2,2,3,3,3 ,4,4,4,5,5,6,6, 6]
      Enigma> pylab.hist(x_va lues,6) pylab.show()

      Enigma> This produced the following image:
      Enigma> http://enigmacurry.com/usenet/histor...grid-lines.png

      Enigma> Starting with bar number 2, it creeps into grid 1.. and
      Enigma> finally with bar number 5 it's almost entirely in grid
      Enigma> 4.. how do I make the bars stay in their own grid lines?

      While exactly what you want is something of an enigma to me, I can
      offer some advice and terminology. The bars of hist make no attempt
      to stay within the bounds of the grid lines... The bars have as their
      left most boundary the bins you choose for the histogram. As a first
      step, I suggest setting these bins explicitly, rather than letting the
      hist command choose them automatically

      from pylab import hist, xlim, nx, show

      x_values= [1,1,2,2,2,3,3,3 ,4,4,4,5,5,6,6, 6]
      bins = nx.arange(0.5, 7.)
      hist(x_values, bins)
      xlim(0,6.5)
      show()

      The grid line locations are determined by the xtick locations, which
      you can set with the xticks command.

      Good luck!
      JDH

      Comment

      • Enigma Curry

        #4
        Re: Matplotlib: Histogram with bars inside grid lines...how??

        Thank you John. Your explanation helped a lot!

        In case it helps anyone else in the future, here is my code for
        *exactly* what I was after:

        import pylab

        def ryan_hist(data, bar_width, min_x, max_x):
        """
        Create a frequency histogram over a continuous interval

        min_x = the low end of the interval
        max_x = the high end of the interval

        bar_width = the width of the bars

        This will correctly align the bars of the histogram
        to the grid lines of the plot
        """
        #Make histogram with bars of width .9 and center
        #them on the integer values of the x-axis
        bins = pylab.nx.arange (1-(bar_width/2),max(data))
        n,bins,patches = pylab.hist(data , bins, width=bar_width )

        #Make Y axis integers up to highest n
        pylab.yticks(py lab.arange(sort ed(n)[-1]))
        pylab.axis('sca led')
        pylab.xlim(0.5, 6.5)
        pylab.grid()
        pylab.show()

        #Create a historgram
        data=[1,1,2,2,2,2,2,2 ,3,3,3,4,4,4,5, 5,6,6,6]
        bar_width = 0.9
        ryan_hist(data, bar_width,min(d ata),max(data))

        Comment

        • Enigma Curry

          #5
          Re: Matplotlib: Histogram with bars inside grid lines...how??

          pylab.xlim(0.5, 6.5)

          should be:

          pylab.xlim(min_ x-(bar_width/2),max_x+(bar_w idth/2))

          Comment

          • John Hunter

            #6
            Re: Matplotlib: Histogram with bars inside grid lines...how??

            >>>>> "Enigma" == Enigma Curry <workbee@gmail. com> writes:

            Enigma> pylab.xlim(0.5, 6.5) should be:

            Enigma> pylab.xlim(min_ x-(bar_width/2),max_x+(bar_w idth/2))

            Glad it's working better for you -- just a couple more smallish hints.

            You might prefer to have your grid lines behind, rather than above the
            bars. In that case create the subplot or axes with the axisbelow=True
            kwarg. Despite the fact that you found the kwargs a little annoying
            at first, you will probably come to love them. matplotlib makes very
            heavy use of them and they are very useful since they allow matplotlib
            to usually do the right things while exposing most of the settings to
            you. Eg

            plot(x, y,
            linewidth=2, linestyle='--',
            marker='o', markerfacecolor ='r', markeredgecolor ='g'
            markeredgewith= 2, markersize=10)

            and so on. There are lots of properties you can set on almost every
            command. Because noone wants to type all that, you can use aliases

            plot(x, y, lw=2, ls='--', marker='o', mfc='r', mec='g', mew=2, ms=10)


            Secondly, in your example, you are relying implicitly on matplotlib to
            pick integer ticks for the xaxis. It's doing it right in this
            example, but might prefer other tick locations for other examples
            depending on your x_values. So set xticks explicitly.

            Below is a slightly modified example showing these two ideas.

            You also might want to consider joining the mailing list at

            Matplotlib is a python library for making publication quality plots using a syntax familiar to MATLAB users. Matplotlib uses numpy for numerics.…


            since you appear to be a little finicky about your figures :-)

            def ryan_hist(data, bar_width, min_x, max_x):
            """
            Create a frequency histogram over a continuous interval

            min_x = the low end of the interval
            max_x = the high end of the interval

            bar_width = the width of the bars

            This will correctly align the bars of the histogram
            to the grid lines of the plot
            """
            #Make histogram with bars of width .9 and center
            #them on the integer values of the x-axis
            bins = pylab.nx.arange (1-(bar_width/2),max(data))
            pylab.subplot(1 11, axisbelow=True)
            n,bins,patches = pylab.hist(data , bins, width=bar_width )

            #Make Y axis integers up to highest n
            pylab.yticks(py lab.arange(max( n)))
            pylab.xticks(py lab.arange(max( n)+1))
            pylab.axis('sca led')
            pylab.xlim(min_ x-(bar_width/2),max_x+(bar_w idth/2))
            pylab.grid()
            pylab.show()


            Comment

            Working...