Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAINT: fix marker size type mismatch error #859

Merged
merged 19 commits into from
May 16, 2023
Merged

Conversation

homosapien-lcy
Copy link
Contributor

@homosapien-lcy homosapien-lcy commented Mar 13, 2023

The ScatterPlot1D specifies marker_size = Float(4.0) while the downstream render_markers function is supposed to handle both single numeric data and arrays. This PR changes this.

Address #846

@homosapien-lcy
Copy link
Contributor Author

close issue #846

marker_size = Float(4.0)
marker_size = Union(Float, Int,
Array(Float), Array(Int),
default_value=None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why changing the defaut to None? The 4.0 value was a good default. By changing the default, you now have to update the _render method.

The upstream issue was related to the fact that only floats were supported. Using a Union type, you now allow other data type, which is solving the problem. Adding a tests that reproduces the uptsream problem would be good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I somehow remembered that using 4.0 as default will raise an error, but after retest, works fine... Will use 4.0 instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@homosapien-lcy adding a new manual example is not adding a test!
As discussed, tests are based on the unittest.TestCase in order too be picked up by the CI and shoud be added here: https://github.com/enthought/chaco/blob/main/chaco/plots/tests/test_scatterplot_1d.py

@@ -32,7 +32,9 @@ class ScatterPlot1D(Base1DPlot):
marker = MarkerTrait

# The pixel size of the marker, not including the thickness of the outline.
marker_size = Float(4.0)
marker_size = Union(Float, Int,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Float trait should already accept integers, so I'm not sure that it adds much to accept Int here, especially given that the marker size is conceptually a float here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I found that Float trait can accomodate int as well, just cahnged.

@@ -32,7 +32,9 @@ class ScatterPlot1D(Base1DPlot):
marker = MarkerTrait

# The pixel size of the marker, not including the thickness of the outline.
marker_size = Float(4.0)
marker_size = Union(Float, Int,
Array(Float), Array(Int),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't how the Array trait works - you need to supply a dtype as the argument, not a trait type. As it stands, this would accept an array with any dtype.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks!

@dpinte
Copy link
Member

dpinte commented Mar 24, 2023

@homosapien-lcy as next step, we discussed:

  • add a test case reproducing the upstream issue, that should surface the problem that @mdickinson has highlighted with the way you use the Array trait
  • fix the current version of the code and make sure the test pass
  • add tests cases for the various other use case you cover in the new Union (and verify that as Mark suggests, it's not needed to add the Int trait in the Union)

Copy link
Member

@dpinte dpinte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@homosapien-lcy some comments to address on the test.

@@ -32,7 +32,9 @@ class ScatterPlot1D(Base1DPlot):
marker = MarkerTrait

# The pixel size of the marker, not including the thickness of the outline.
marker_size = Float(4.0)
marker_size = Union(Float,
Array(float),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make the keyword argument explicit with dtype=float



class Scatter1DTestCase(unittest.TestCase):
# test the default value 4.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that comment line can be removed in favour of a clear method name or moved as a docstring to the test method.


class Scatter1DTestCase(unittest.TestCase):
# test the default value 4.0
def test_default(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggests test_default_marker_size rather than test_default

orientation="v",
marker="plus",
alignment="left"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nothing is really being tested here. What do you expect to test? Verify that something is generated without exception? ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is applicable to all the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these tests are limited to check for traits mismatch exceptions. Is there other stuffs we want to test?

Copy link
Contributor

@corranwebster corranwebster Apr 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a test of the default marker size, you should somewhere have a line like self.assertEqual(..., 4.0)

)

# test integer marker size
def test_int(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment on the method name and the removal of the comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comments, updates made

Copy link
Contributor

@corranwebster corranwebster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure what the point of this PR is. The 1D scatterplot doesn't currently support variable size markers (or variable color or shape, for that matter). It could, potentially, but it doesn't right now, and this PR is not correct in its approach. Chaco is a dynamoc plotting library and all data needs to be passed via appropriate objects that manage changes to the data. For example, the example usage will fail if the using code changes the size of the data array holding the values.

To be fair, it looks like there is an error in the corresponding Trait declarations for the 2D scatterplot: the following is not correct either (edit: as is noted in the "TODO")

# The pixel size of the markers, not including the thickness of the outline.
# Default value is 4.0.
# TODO: for consistency, there should be a size data source and a mapper
marker_size = Union(Float, Array, requires_redraw=True)

A correct implementation would use a data source for the sizes (and possibly a mapper as well), the way that the colormapped scatterplot does for colors:

#: Source for color data.
color_data = Instance(ArrayDataSource)

It would also have to add support for finding the data source in the Plot object code, eg. somewhere in here:

chaco/chaco/plot.py

Lines 1270 to 1296 in f32e01c

if plot_type in ("scatter_1d", "line_scatter_1d", "jitterplot"):
# simple 1d positional plots with no associated value
for source in data:
index = self._get_or_create_datasource(source)
index_range.add(index)
if scale == "linear":
imap = LinearMapper(
range=index_range,
stretch_data=index_mapper.stretch_data,
)
else:
imap = LogMapper(
range=index_range,
stretch_data=index_mapper.stretch_data,
)
cls = self.renderer_map[plot_type]
plot = cls(
index=index,
index_mapper=imap,
orientation=orientation,
direction=direction,
**styles
)
plots.append(plot)
self.add(plot)

Comment on lines 35 to 37
marker_size = Union(Float,
Array(dtype=float),
default_value=4.0)
Copy link
Contributor

@corranwebster corranwebster Apr 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is absolutely not correct - Chaco data never comes from hard-coded arrays like this. Most likely this should be a Float or an Instance(AbstractDataSource).

orientation="v",
marker="plus",
alignment="left",
marker_size=randint(1,5, numpts)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the correct usage and should fail. You would need to specify a data source for the size values which holds the sizes.

orientation="v",
marker="plus",
alignment="left"
)
Copy link
Contributor

@corranwebster corranwebster Apr 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a test of the default marker size, you should somewhere have a line like self.assertEqual(..., 4.0)

# Thanks for using Enthought open source!

"""
Unit tests for scatter_1d function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@homosapien-lcy
Copy link
Contributor Author

With Corran's comments, after discussing with Didrik, we think:

1 the "error" that the user reported in #846 is actually the expected behavior of the test, thus there is no need to change the scatterplot class to enable different types of inputs
2 the confusion comes from the fact that in chaco/examples/demo/basic/scatter_1d, a line "# randint(1,5, numpts)," is commented out in line 78, suggesting the users that the input may be an array of integers.

With the above observations, we decided to simply delete the commented out line mentioned in 2 to avoid confusion as the solution to the issue closes #846

@dpinte dpinte merged commit fa42199 into main May 16, 2023
@dpinte dpinte deleted the fix_scatter_plot_type_error branch May 16, 2023 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants