On Thu, May 5, 2011 at 7:16 PM, Paul Leopardi <paul.leopa...@iinet.net.au>wrote:

> [Repost from 21 Mar 2011: note suggested patches]
>
> Hi all,
> I am using Matplotlib 1.0.1 and am seeing weird behaviour with mplot3d and
> ticker formatters, and I think I need to submit a patch to axes3d, but am
> not
> sure how much it will break, because format_zdata() and format_coord() look
> to
> be defined inconsistently.
>
> When trying to rotate a plot, which was created including the following
> commands,
>  ...
>  ax.plot(x[0,alow:atop],x[1,alow:atop],x[2,alow:atop],c=rgb.tolist())
>  ax.w_xaxis.set_major_locator(tic.LinearLocator(3))
>  ax.w_xaxis.set_major_formatter(tic.FormatStrFormatter(''))
>  ax.w_yaxis.set_major_locator(tic.LinearLocator(3))
>  ax.w_yaxis.set_major_formatter(tic.FormatStrFormatter(''))
>  ax.w_zaxis.set_major_locator(tic.LinearLocator(3))
>  ax.w_zaxis.set_major_formatter(tic.FormatStrFormatter(''))
>  plt.draw()
>  ...
>
> I received the following backtrace and error message:
>
> /usr/lib64/python2.6/site-packages/matplotlib/backend_bases.pyc in
> mouse_move(self, event)
>   2393         if event.inaxes and event.inaxes.get_navigate():
>   2394
> -> 2395             try: s = event.inaxes.format_coord(event.xdata,
> event.ydata)
>   2396             except ValueError: pass
>   2397             except OverflowError: pass
>
> /usr/lib64/python2.6/site-packages/mpl_toolkits/mplot3d/axes3d.pyc in
> format_coord(self, xd, yd)
>    474
>    475         xs = self.format_xdata(x)
> --> 476         ys = self.format_ydata(y)
>    477         zs = self.format_ydata(z)
>    478         return 'x=%s, y=%s, z=%s' % (xs, ys, zs)
>
> /usr/lib64/python2.6/site-packages/mpl_toolkits/mplot3d/axes3d.pyc in
> format_ydata(self, y)
>    424         except TypeError:
>    425             fmt = self.w_yaxis.get_major_formatter()
> --> 426             return sensible_format_data(fmt, y)
>    427
>    428     def format_zdata(self, z):
>
> /usr/lib64/python2.6/site-packages/mpl_toolkits/mplot3d/axes3d.pyc in
> sensible_format_data(self, value)
>     26     if abs(value) > 1e4 or abs(value)<1e-3:
>     27         s = '%1.4e' % value
> ---> 28         return self._formatSciNotation(s)
>     29     else:
>     30         return '%4.3f' % value
>
> AttributeError: FormatStrFormatter instance has no attribute
> '_formatSciNotation'
>
> ---
> I am using FormatStrFormatter('') to try to obtain an empty tick.
>
> [1] It looks like sensible_format_data() assumes that self is class
> ScalarFormatter(Formatter), since this is the only ticker Formatter that
> has
> attribute _formatSciNotation(s). As far as I can tell, this means that
> sensible_format_data(fmt,y) should *only* be called if fmt has class
> ScalarFormatter(Formatter).
>
>
> [2] In axes3d.py, I see:
>
>    def format_zdata(self, z):
>        """
>        Return z string formatted.  This function will use the attribute
>        self.fmt_zdata if it is callable, else will fall back on the yaxis
>        major formatter
>        """
>        try:
>            return self.fmt_zdata(z)
>        except (AttributeError, TypeError):
>            fmt = self.w_zaxis.get_major_formatter()
>            return sensible_format_data(fmt, z)
>
> To me, it looks like the call to sensible_format_data(fmt, z) is wrong. The
> same error occurs in format_xdata() and format_ydata(). So I would like to
> submit a patch for format_xdata(), format_ydata(), format_zdata(), e.g.:
>
>    def format_zdata(self, z):
>        """
>        Return z string formatted.  This function will use the attribute
>        self.fmt_zdata if it is callable, else will fall back on the zaxis
>        major formatter
>        """
>        try:
>            return self.fmt_zdata(z)
>        except (AttributeError, TypeError):
>            fmt = self.w_zaxis.get_major_formatter()
>            try:
>                return sensible_format_data(fmt, z)
>            except (AttributeError, TypeError):
>                return format_data(fmt, z)
>
>
> [3] But I am also worried about the comment "else will fall back on the
> yaxis
> major formatter". Shouldn't this say "the zaxis major formatter", since
> that
> is what the code does? Or should the code use the yaxis major formatter,
> since
> that is what the documentation says? The documentation
> http://matplotlib.github.com/mpl_toolkits/mplot3d/api.html agrees with the
> comment and not with the code.
>
>
> [4] In def format_coord(self, xd, yd), I see
>
>        xs = self.format_xdata(x)
>        ys = self.format_ydata(y)
>        zs = self.format_ydata(z)
>
> Why doesn't the last line say
>        zs = self.format_zdata(z)
> ?
>
> Best, Paul
>
>
Paul,

This is a perfect example of the "with many eyes, all bugs are shallow"
saying.  I have been running into problems with this with respect to getting
log scales to work.  While your fixes doesn't completely address the issue,
it does bring me a few steps closer.

Your hunches are correct.  There have been plenty of copy-n-paste mistakes
within mplot3d, and it makes no sense to fall back onto the y-axis
formatter.  Also, note that the documentation is automatically generated
from the string comments, so it is no surprise that they match.

I will make a patch for this for master and hopefully v1.0.x.

Thank you,
Ben Root
------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network 
management toolset available today.  Delivers lowest initial 
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to