matplotlib-0.50 alpha release - try it out!

I've spent the last couple of days refactoring the matplotlib
backends, fixing bugs and adding some functionality. Here's a
synopsis of what's new. I encourage everyone to try it out so
complaints and bugs can be handled before the major release.

** Note there are some API changes so please read about this below **

** Note, GD users, GD rendering is significantly improved in my
   opinion. However, some of new functionality requires a recent
   version of gd and a patch of the latest gdmodule, see below **

What's new in matplotlib 0.50e

  GD supports clipping and antialiased line drawing. The line object
  has a new 'antialiased' property, that if true, the backend will
  render the line antialiased if supported. **You will need to
  upgrade to gd-2.0.15 or later and gdmodule-0.51. You will also need
  to replace _gdmodule.c with the code as described at
  http://matplotlib.sourceforge.net/backends.html#GD.

wild and wonderful bar charts

  You can provide an optional argument 'bottom' to the bar command to
  determine where the bottom of each bar is, default 0 for all. This
  enables stacked bar plots and candelstick plots --
  examples/bar_stacked.py. Thanks to David Moore and John Gill for
  suggestions and code.

Bugfixes (by backend)

    * All : the yticks on the right hand side were placed incorrectly,
      now fixed

    * All : ticklabels now make a more intelligent choice about how
      many significant digits to display

    * GD : An int truncation bug was causing the dotted lines to
      disappear

    * GD and GTK : Fixed line width to scale with DPI

    * GD : Fixed small text layout bug

    * GD : Fixed the constant for GD which maps pixels per inch - this
      should give better agreement with other backends witht he
      relative sizes of objects

    * GTK : Dash spacing was not properly scaling with DPI

Figure backend refactored

  The figure functionality was split into a backend independent
  component Figure and a backend dependent component
  FigureCanvasBase. This completes the transition to a totally
  abstract figure interface and improves the ability the switch
  backends. See the file
  http://matplotlib.sourceforge.net/API_CHANGES that comes with the
  src distro for information on migrating applications to the new API.
  All the backend specific examples have been updated to the new API.

Enjoy,
John Hunter

Hi,

I am happily using matplotlib-0.50e. I tried eps output and it worked very
nicely. The problem with plot lines not being clipped by a manual axis in
the PS backend also seems to have been fixed.

...

I have some feedback on the default tick behaviour. matplotlib seems to
pick a number of ticks, and then divides through to get the tick values.
This results in some ugly long tick labels, making it hard to quickly
gauge the range between two points on a graph.

E.g. if the y range of a plot is 1.927 to 1.948, then matplotlib puts
ticks at (1.927, 1.931, 1.935, ..., 1.948)

I think it would be better (and closer to the plotting behaviour of
other software) if matplotlib picked ticks that were "round", even if that
means the endpoints of the axes are slightly outside the range of the
data.

So the ticks for the example above would become:
(1.925, 1.930, 1.935, ..., 1.950)

I guess this would be more complicated to implement than the current
algorithm, but it would make life easier when interpreting graphs from
matplotlib!

...

Another slight niggle. If I set the axis range manually, then if a data
point is exactly equal to the end of the axis range then it won't be
plotted. Making the axis range slightly longer is clumsy. This also
violates the principle of least surprise, because automatic axis ranges do
not have this behaviour. A simple way to see the problem is to compare the
output of the two plots below:

xvals = arange(0.0, 1.0, 0.1)
plot(xvals, [sin(x) for x in xvals])

[<matplotlib.lines.Line2D instance at 0x93fa844>]

show()
plot(xvals, [sin(x) for x in xvals])

[<matplotlib.lines.Line2D instance at 0x9249d2c>]

autoaxis = axis()
autoaxis

[0.0, 0.90000000000000002, 0.0, 0.80000000000000004]

axis(autoaxis)
show()

Presumably the logic for picking the datapoints to plot should use <= not
<.

Cheers,
Matthew.

Hi again,

I'm having more trouble with matplotlib ticks today. I wrote a little demo
script that illustrates some of the problems:

...

#!/usr/bin/python

from matplotlib.matlab import *

xx = arange(0.002, 0.0101, 0.001)
print xx
# an instance of yy = rand(9), so all values are between 0 and 1
yy = [ 5.94692328e-04, 1.62328354e-01, 7.56822907e-01, 2.28180047e-02,
        3.23820274e-01, 3.93120900e-01, 6.41332889e-01, 1.22474302e-02,
        5.03485402e-01]
subplot(211)
plot(xx, yy)
subplot(212)
plot(xx, yy)
autoaxis = axis()
print autoaxis
axis(autoaxis)
show()

...

* the x axis includes *two* 0.004 and *two* 0.008; this really worried me
until I realised it was a cosmetic rounding / significant figures issue,
however it's bad enough to be seriously misleading. I think the actual
tick values are something like 0.0036 and 0.0044 but are both rounded to
0.004.

* the data points lie *between* the x axis ticks, this is a side-effect of
the above

* the poor choice of tick positions on the y axis -- they should be
in round numbers like 0.2, 0.4, etc. The most significant varying figure
should be a multiple of 1, 2, or 5.

* the tick labels should all have the same number of significant figures,
e.g. 0.00, 0.15, 0.30, 0.45, 0.60, ... for the y axis

* after manually setting the axis (lower subplot), the last point is not
plotted

I hope you find this feedback useful. I had a go at fixing it in axis.py,
but it's a) fiddly and b) I don't quite understand which part has
precendence when the axis changes during a zoom or pan. Getting the ticks
right depends on the correct bounds for the axis and the choice of
numticks. I noticed you have logic to clean up the bounds (vmin and vmax)
but not the ticklocs.

Thanks for matplotlib.

Cheers,
Matthew.