[matplotlib-devel] Data limit oddity when combining normal line and axvline collections

2010-08-18 Thread Ludwig Schwardt
Hi,

I am hesitant to call the following a bug. It might just be a
misunderstanding on my side. Anyhow...

I am plotting a normal line collection and an "axvline" collection on
the same Axes. The latter is a collection of lines with data
coordinates for x and axes coordinates for y, using a blended
transform. I find that the data limits are messed up by the axvline
collection, which unexpectedly sets the bottom y limit to 0. This
results in a badly scaled plot when adjusting the view with
autoscale_view. Interestingly, this problem goes away if the normal
line collection is viewed first via autoscale_view, if the normal line
collection is replaced by a normal plot command, or if the axvline
collection is replaced by a normal axvline command. The problem
appears if the two collections are added to the Axes without an
autoscale_view in between.

I ran the code below with matplotlib trunk (SVN r8646) on Mac OS 10.5
with TkAgg backend. The same behaviour appears in matplotlib 0.99.1.1.
Please let me know if I am doing something obviously stupid,
especially in the way I create the axvline collection. At the moment I
am working around the behaviour by inserting an autoscale_view between
the two collections, so it is not a major show-stopper.

Regards,
Ludwig


### Start code snippet ###

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# Create sine wave to plot (offset from zero)
t = np.arange(200)
x = 10 + np.cos(2 * np.pi * t / 20)

plt.figure(1)
plt.clf()
ax = plt.gca()

# Add main plot as a line collection containing one segment
segments = mpl.collections.LineCollection([zip(t, x)])
ax.add_collection(segments)
print ax.dataLim
# Output: Bbox(array([[   0.,9.], [ 199.,   11.]]))

# Uncommenting the line below actually fixes the problem...
#ax.autoscale_view()

# Add break lines as a collection of axvlines
breaks = np.arange(0, 200, 20)
transFixedY = mpl.transforms.blended_transform_factory(ax.transData,
ax.transAxes)
break_lines = mpl.collections.LineCollection([[(s, 0), (s, 1)] for s
in breaks], transform=transFixedY, colors='k', linewidths=0.5,
linestyles='dotted')
ax.add_collection(break_lines)
print ax.dataLim
# Output: Bbox(array([[   0.,0.], [ 199.,   11.]]))
# Notice that y0 is now 0 instead of the expected 9

# Autoscaling now inserts a lot of space below the original plot
ax.autoscale_view()

### End code snippet ###

--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] Colormap that prints nicely in black and white

2010-08-18 Thread Benjamin Root
On Tue, Aug 17, 2010 at 4:19 PM, Friedrich Romstedt <
friedrichromst...@gmail.com> wrote:

> 2010/8/17 Benjamin Root :
> > "...it will not be necessary..."
> >
> > I think we are still getting confused here.  I was listing off several
> > different kinds of use-cases where one would like to have a mix of grey
> > colormaps and colored colormaps.  The reason I mention being able to save
> a
> > greyscale and a color version of the same figure is in the context of my
> > approach to solving this problem (the swapping out of colormaps).
> Honestly,
> > I think that your approach is better for dealing with that particular use
> > case.
>
> Okay, may be you're right and we should include the usecase you're
> having in mind.
>
> > However, I mention other cases where one is merely wanting a modified
> > version of a particular colormap to use, be it greyscale, or inverse, or
> > brighter/darker, etc.
>
> Yes, that's neat.
>
> >  What I envision your solution to be solving would be
> > something like this:
>
> > fig = plt.figure()
> > ax = fig.add_subplot(1, 2, 1)
> > ax.plot(np.linspace(1, 10, 10), np.linspace(2, 8, 10))
> > ax.plot(np.linspace(1, 10, 10), np.linspace(4, 9, 10))
> >
> > ax = fig.add_subplot(1, 2, 2)
> > ax.set_grey(True)
> > ax.plot(np.linspace(1, 10, 10), np.linspace(1, 8, 10))
> > ax.plot(np.linspace(1, 10, 10), np.linspace(3, 7, 10))
> > ax.plot(np.linspace(1, 10, 10), np.linspace(2, 9, 10))
>
> Hmm, that's much more complicated ... For Collections, one could set a
> local flag, but it would be nevertheless quite buried in the API ...
> When setting it in the axes, one has to care about all artists added
> later too, and all pathes an artist may sneak into the axes.
>
>
I had a thought... and it is based on my admittedly incomplete understanding
of matplotlib.  Everything that gets drawn is derived from the artist class,
right?  So, what if there was a 'grey' boolean in that base class, and the
.draw() function passes that bool down through all the subsequent .draw()
calls of its child objects (it could be None by default to accept the
parent's property, or allowed to be explicitly set by the user to override
the parent's value.)

By the time we get to the backends, all the color data should be in a clean,
broadcasted rgba form, so it should then be a relatively simple check of the
grey flag before writing out the color information.

Admittedly, I would much rather have this flag check done before getting to
the backends and through a single point of code.  At first, I thought that
ColorConverter would be it, but as I now understand it, it is treated more
like a utility module rather than an important step in the rendering
process.  It gets used for things at different points in the matplotlib
process.

Maybe I am just going overboard here...


> What I'm going to solve is simply a toplevel boolean 'gray' switch in
> the rcParams.  It's working in an abstract way.
>
> Maybe a complementary approach would be useful.  A global switch for
> everything, and more fine-tuning control coming from your side?
>
>
I think the issue with my approach is that it would only impact things that
uses colormaps.  Anything that explicitly sets its colors without a colormap
will be totally unaffected.


> For the "road map", I cannot put myself under strong pressure with
> this, I would say, although being a rather tiny thing, I will finish
> it until end of next week.
>
>
Can't wait to see what you have.


> Ahh, and shall we name the switch 'gray' or 'grey'
>
>
Heh, even matplotlib can't provide too much precedence here because it tries
to cater to both spellings (and I keep flipping back and forth due to a
stupid bug in the Ubuntu packaging that packaged a en_UK spell-checker
instead of en_US, but my Fedora setup has it right...).  I should note that
for Colormaps, there is only a "is_gray" function.

Cheers,
Ben Root
--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev ___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


[matplotlib-devel] small patch for trunk/matplotlib/lib/matplotlib/axis.py

2010-08-18 Thread Daniel Hyams
This is a small patch to enable get_gridlines to be able to get the grid
lines for the minor ticks as well.

1052c1052
< def get_gridlines(self):
---
> def get_gridlines(self,minor=False):
1054c1054,1055
< ticks = self.get_major_ticks()
---
> if minor: ticks = self.get_minor_ticks()
> else: ticks = self.get_major_ticks()



-- 
Daniel Hyams
dhy...@gmail.com
--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev ___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


[matplotlib-devel] ax.scatter broken for triangular markers

2010-08-18 Thread Thomas Robitaille
Hi,

I updated to the latest svn version of matplotlib this morning, and 
Axes.scatter seems to be broken when using marker='v', '>', '<', or '^':

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as mpl

fig = mpl.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter([1,2,3], [4,5,6], marker='v')
fig.savefig('test.png')

gives:

Traceback (most recent call last):
  File "test.py", line 7, in 
ax.scatter([1,2,3], [4,5,6], marker='^')
  File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/axes.py", line 
5764, in scatter
transOffset = self.transData,
  File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/collections.py", 
line 695, in __init__
self._paths = [self._path_generator(numsides)]
  File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/path.py", line 
415, in unit_regular_polygon
path = cls(verts, codes)
  File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/path.py", line 
117, in __init__
assert len(codes) == len(vertices)
AssertionError

This did not occur when I updated to the latest svn a couple of days ago, so it 
must be due to a pretty recent change.

Cheers,

Tom
--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] ax.scatter broken for triangular markers

2010-08-18 Thread Michael Droettboom
Should be fixed in r8648 now.

Mike

On 08/18/2010 11:45 AM, Thomas Robitaille wrote:
> Hi,
>
> I updated to the latest svn version of matplotlib this morning, and 
> Axes.scatter seems to be broken when using marker='v', '>','<', or '^':
>
> import matplotlib
> matplotlib.use('Agg')
> import matplotlib.pyplot as mpl
>
> fig = mpl.figure()
> ax = fig.add_subplot(1,1,1)
> ax.scatter([1,2,3], [4,5,6], marker='v')
> fig.savefig('test.png')
>
> gives:
>
> Traceback (most recent call last):
>File "test.py", line 7, in
>  ax.scatter([1,2,3], [4,5,6], marker='^')
>File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/axes.py", 
> line 5764, in scatter
>  transOffset = self.transData,
>File 
> "/Users/tom/Library/Python/2.6/site-packages/matplotlib/collections.py", line 
> 695, in __init__
>  self._paths = [self._path_generator(numsides)]
>File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/path.py", 
> line 415, in unit_regular_polygon
>  path = cls(verts, codes)
>File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/path.py", 
> line 117, in __init__
>  assert len(codes) == len(vertices)
> AssertionError
>
> This did not occur when I updated to the latest svn a couple of days ago, so 
> it must be due to a pretty recent change.
>
> Cheers,
>
> Tom
> --
> This SF.net email is sponsored by
>
> Make an app they can't live without
> Enter the BlackBerry Developer Challenge
> http://p.sf.net/sfu/RIM-dev2dev
> ___
> Matplotlib-devel mailing list
> Matplotlib-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>


-- 
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
Baltimore, Maryland, USA


--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] ax.scatter broken for triangular markers

2010-08-18 Thread Thomas Robitaille
I can confirm that this now works fine - thanks for the quick fix!

Tom

On Aug 18, 2010, at 12:09 PM, Michael Droettboom wrote:

> Should be fixed in r8648 now.
> 
> Mike
> 
> On 08/18/2010 11:45 AM, Thomas Robitaille wrote:
>> Hi,
>> 
>> I updated to the latest svn version of matplotlib this morning, and 
>> Axes.scatter seems to be broken when using marker='v', '>','<', or '^':
>> 
>> import matplotlib
>> matplotlib.use('Agg')
>> import matplotlib.pyplot as mpl
>> 
>> fig = mpl.figure()
>> ax = fig.add_subplot(1,1,1)
>> ax.scatter([1,2,3], [4,5,6], marker='v')
>> fig.savefig('test.png')
>> 
>> gives:
>> 
>> Traceback (most recent call last):
>>   File "test.py", line 7, in
>> ax.scatter([1,2,3], [4,5,6], marker='^')
>>   File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/axes.py", 
>> line 5764, in scatter
>> transOffset = self.transData,
>>   File 
>> "/Users/tom/Library/Python/2.6/site-packages/matplotlib/collections.py", 
>> line 695, in __init__
>> self._paths = [self._path_generator(numsides)]
>>   File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/path.py", 
>> line 415, in unit_regular_polygon
>> path = cls(verts, codes)
>>   File "/Users/tom/Library/Python/2.6/site-packages/matplotlib/path.py", 
>> line 117, in __init__
>> assert len(codes) == len(vertices)
>> AssertionError
>> 
>> This did not occur when I updated to the latest svn a couple of days ago, so 
>> it must be due to a pretty recent change.
>> 
>> Cheers,
>> 
>> Tom
>> --
>> This SF.net email is sponsored by
>> 
>> Make an app they can't live without
>> Enter the BlackBerry Developer Challenge
>> http://p.sf.net/sfu/RIM-dev2dev
>> ___
>> Matplotlib-devel mailing list
>> Matplotlib-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>> 
> 
> 
> -- 
> Michael Droettboom
> Science Software Branch
> Space Telescope Science Institute
> Baltimore, Maryland, USA
> 
> 
> --
> This SF.net email is sponsored by 
> 
> Make an app they can't live without
> Enter the BlackBerry Developer Challenge
> http://p.sf.net/sfu/RIM-dev2dev 
> ___
> Matplotlib-devel mailing list
> Matplotlib-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] small patch for trunk/matplotlib/lib/matplotlib/axis.py

2010-08-18 Thread Ryan May
On Wed, Aug 18, 2010 at 9:25 AM, Daniel Hyams  wrote:
> This is a small patch to enable get_gridlines to be able to get the grid
> lines for the minor ticks as well.
> 1052c1052
> <     def get_gridlines(self):
> ---
>>     def get_gridlines(self,minor=False):
> 1054c1054,1055
> <         ticks = self.get_major_ticks()
> ---
>>         if minor: ticks = self.get_minor_ticks()
>>         else:     ticks = self.get_major_ticks()

Thanks for the contribution. Can you regenerate using: diff -u
so we can easily apply to the tree?

Thanks,

Ryan

-- 
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] small patch for trunk/matplotlib/lib/matplotlib/axis.py

2010-08-18 Thread Daniel Hyams
Sure:

--- axis.py 2010-08-18 09:59:25.0 -0400
+++ axis.py.orig2010-08-18 09:58:13.0 -0400
@@ -1049,12 +1049,9 @@
 def _get_offset_text(self):
 raise NotImplementedError('Derived must override')

-def get_gridlines(self,minor=False):
+def get_gridlines(self):
 'Return the grid lines as a list of Line2D instance'
-if minor:
-   ticks = self.get_minor_ticks()
-else:
-   ticks = self.get_major_ticks()
+ticks = self.get_major_ticks()
 return cbook.silent_list('Line2D gridline', [tick.gridline for tick
in ticks])

 def get_label(self):


On Wed, Aug 18, 2010 at 1:05 PM, Ryan May  wrote:

> On Wed, Aug 18, 2010 at 9:25 AM, Daniel Hyams  wrote:
> > This is a small patch to enable get_gridlines to be able to get the grid
> > lines for the minor ticks as well.
> > 1052c1052
> > < def get_gridlines(self):
> > ---
> >> def get_gridlines(self,minor=False):
> > 1054c1054,1055
> > < ticks = self.get_major_ticks()
> > ---
> >> if minor: ticks = self.get_minor_ticks()
> >> else: ticks = self.get_major_ticks()
>
> Thanks for the contribution. Can you regenerate using: diff -u
> so we can easily apply to the tree?
>
> Thanks,
>
> Ryan
>
> --
> Ryan May
> Graduate Research Assistant
> School of Meteorology
> University of Oklahoma
>



-- 
Daniel Hyams
dhy...@gmail.com
--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev ___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] Colormap that prints nicely in black and white

2010-08-18 Thread Friedrich Romstedt
2010/8/18 Benjamin Root :
> I had a thought... and it is based on my admittedly incomplete understanding
> of matplotlib.  Everything that gets drawn is derived from the artist class,
> right?  So, what if there was a 'grey' boolean in that base class, and the
> .draw() function passes that bool down through all the subsequent .draw()
> calls of its child objects (it could be None by default to accept the
> parent's property, or allowed to be explicitly set by the user to override
> the parent's value.)

It's a neat idea again.  I like it very much.  I propose the following:

1)  As you said, a gray flag in mpl.artist.Artist, which can be
automatically transmitted to the child artists *on render time*.

2)  Counting the "grayishness" (single, double, ... :-) in
mpl.backends.renderer_bases.RendererBase.

3)  Evaluating the grayishness in
mpl.backends.renderer_bases.RendererBase.new_gc() [i.e., new graphics
context].  Passing it on to the GraphicsContext as initialisaion
argument.  mpl.backends.renderer_bases.GraphicsContextBase has ONLY
ONE COLOUR ARGUMENT, namely .set_foreground().  It seems everythings
breaks down to foreground rendering of pathes and symbols.  Indeed, it
uses once again mpl.colors.colorConverter, and I think my refactoring
of this one is not useless at all, but the main point is, it stores an
rgb colour in the end, and in fact *all* rgb colours ever used in any
graphics drawing context.  Also for text, etc. pp.

4)  Introducing a decorator:

def draw_with_grayishness(fn):
def decorated(self, renderer):
if self.is_gray():
renderer.increase_grayishness()
fn(self, renderer)
renderer.decrease_grayishness()
else:
fn(self, renderer)

return decorated

This turns on grayishness in the renderer if it is requested by
*self*, which is an Artist.

> By the time we get to the backends, all the color data should be in a clean,
> broadcasted rgba form, so it should then be a relatively simple check of the
> grey flag before writing out the color information.

Mmmh, for some reason colorConverter is used there again, maybe historical.

> Admittedly, I would much rather have this flag check done before getting to
> the backends and through a single point of code.  At first, I thought that
> ColorConverter would be it, but as I now understand it, it is treated more
> like a utility module rather than an important step in the rendering
> process.  It gets used for things at different points in the matplotlib
> process.

Yes, it's not the only point, there is at least one more,
mpl.collection.Collection.update_scalaramappable().  And there may be
tons of other selfish procedures ... So I agree fully with you.

> Maybe I am just going overboard here...

Well, I come with you :-)

So, the code point would be outside of the Renderer, but in the
GraphicsContext, which is abstract enough to be shared by all
implementations of the rendering.  It is passed on to the
implementation's methods as an argument, so its .foreground or
whatever is the same to all rendering implementations.

Friedrich

--
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel