Loss of filled vs. stroked distinction by Collections

I think of artists as having visual properties that persist (e.g.,
filled vs. outlined, a colormap with min and max values) even as data
associated with the artist is changed. In the edge case described
below, this doesn't seem to hold true.

I have code that animates a scatter plot by sub-selecting the data
stored in a collection artist. In cases where some frames contain no
data, the scatter artist's data is temporarily empty. On subsequent
frames (once there is data again) some of the visual properties my
filled point becomes an outlined point, as in the code below.

# Filled single point with no outline
sc = scatter([1],[1],c=[1], edgecolors='none')

# Cache the data
xy=sc.get_offsets()
s=sc.get_array()

sel=s<0
sc.set_offsets(xy[sel,:])
sc.set_array(s[sel])

# No data, so nothing shown. No problem.
sc.figure.canvas.draw()

# Now restore the original data
sc.set_offsets(xy)
sc.set_array(s)

# Outlined single point with no fill
sc.figure.canvas.draw()
sc.get_edgecolors()
sc.get_facecolors()
sc.get_array()

The fix probably has to do with Collection.update_scalarmappable.
When set_array([ ]) happens,
        len(self._facecolors) > 0, therefore
        self._facecolors = to_rgba([ ]),
When set_array([1]) restores data,
        len(self._facecolors) == 0, therefore
        self._edgecolors = self.to_rgba([1])

Should is_filled vs. is_stroked be preserved in this case? If so, is
there a more elegant fix than to add is_filled and is_stroked
properties that are checked by update_scalarmappable?

Thanks,
Eric

Eric Bruning wrote:

I think of artists as having visual properties that persist (e.g.,
filled vs. outlined, a colormap with min and max values) even as data
associated with the artist is changed. In the edge case described
below, this doesn't seem to hold true.

I have code that animates a scatter plot by sub-selecting the data
stored in a collection artist. In cases where some frames contain no
data, the scatter artist's data is temporarily empty. On subsequent
frames (once there is data again) some of the visual properties my
filled point becomes an outlined point, as in the code below.

# Filled single point with no outline
sc = scatter([1],[1],c=[1], edgecolors='none')

# Cache the data
xy=sc.get_offsets()
s=sc.get_array()

sel=s<0
sc.set_offsets(xy[sel,:])
sc.set_array(s[sel])

# No data, so nothing shown. No problem.
sc.figure.canvas.draw()

# Now restore the original data
sc.set_offsets(xy)
sc.set_array(s)

# Outlined single point with no fill
sc.figure.canvas.draw()
sc.get_edgecolors()
sc.get_facecolors()
sc.get_array()

The fix probably has to do with Collection.update_scalarmappable.
When set_array([ ]) happens,
        len(self._facecolors) > 0, therefore
        self._facecolors = to_rgba([ ]),
When set_array([1]) restores data,
        len(self._facecolors) == 0, therefore
        self._edgecolors = self.to_rgba([1])

Should is_filled vs. is_stroked be preserved in this case? If so, is
there a more elegant fix than to add is_filled and is_stroked
properties that are checked by update_scalarmappable?

I don't see a better way, so I implemented your suggestion.

Eric

Thanks for the fix - works for me on this afternoon's SVN.

-Eric

···

On Mon, Dec 15, 2008 at 1:27 AM, Eric Firing <efiring@...229...> wrote:

Eric Bruning wrote:

I think of artists as having visual properties that persist (e.g.,
filled vs. outlined, a colormap with min and max values) even as data
associated with the artist is changed. In the edge case described
below, this doesn't seem to hold true.

I have code that animates a scatter plot by sub-selecting the data
stored in a collection artist. In cases where some frames contain no
data, the scatter artist's data is temporarily empty. On subsequent
frames (once there is data again) some of the visual properties my
filled point becomes an outlined point, as in the code below.

# Filled single point with no outline
sc = scatter([1],[1],c=[1], edgecolors='none')

# Cache the data
xy=sc.get_offsets()
s=sc.get_array()

sel=s<0
sc.set_offsets(xy[sel,:])
sc.set_array(s[sel])

# No data, so nothing shown. No problem.
sc.figure.canvas.draw()

# Now restore the original data
sc.set_offsets(xy)
sc.set_array(s)

# Outlined single point with no fill
sc.figure.canvas.draw()
sc.get_edgecolors()
sc.get_facecolors()
sc.get_array()

The fix probably has to do with Collection.update_scalarmappable.
When set_array([ ]) happens,
       len(self._facecolors) > 0, therefore
       self._facecolors = to_rgba([ ]),
When set_array([1]) restores data,
       len(self._facecolors) == 0, therefore
       self._edgecolors = self.to_rgba([1])

Should is_filled vs. is_stroked be preserved in this case? If so, is
there a more elegant fix than to add is_filled and is_stroked
properties that are checked by update_scalarmappable?

I don't see a better way, so I implemented your suggestion.

Eric