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