-
Notifications
You must be signed in to change notification settings - Fork 11
Datashader Heatmap Visualization Function #330
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
Open
LizaShch
wants to merge
14
commits into
FNLCR-DMAP:dev
Choose a base branch
from
FNLCR-DMAP:datashader
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
16419e0
Merge pull request #303 from FNLCR-DMAP/histo_title_log
georgezakinih 67929ac
Added datashader 2d scatter function with base usability
LizaShch 636ae5a
Added docstrings and comments to datashader function
LizaShch 855d27d
Merge branch 'FNLCR-DMAP:main' into datashader
ThomasSheeley 439df29
Test Cases: Added test cases for datashaders
LizaShch 1b79d6d
Merge branch 'datashader' of https://github.com/FNLCR-DMAP/spac_datam…
LizaShch 128b60f
Fixed syntax of unit-tests
LizaShch 151b522
Minor Error in Code Syntax
LizaShch d3bc45a
Merge branch 'dev' into datashader
LizaShch 61b927c
Minor changes: refined docstrings and added unit test
LizaShch f75e5e4
style(lines): fixed accidental deletion of lines as well as removed t…
LizaShch 7f09eb8
refactor(auth): Changed parts of datashader to use partial as well as…
LizaShch f2bb3e6
Merge branch 'dev' into datashader
ying39purdue 578ad36
additional formatting to datashader
ying39purdue File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import unittest | ||
| import numpy as np | ||
| import pandas as pd | ||
| from spac.visualization import heatmap_datashader | ||
| import matplotlib | ||
|
|
||
| matplotlib.use('Agg') # Set the backend to 'Agg' to suppress plot window | ||
|
|
||
|
|
||
| class TestDataShaderHeatMap(unittest.TestCase): | ||
| def setUp(self): | ||
| """Prepare data for testing.""" | ||
| self.x = np.random.rand(10) | ||
| self.y = np.random.rand(10) | ||
| # Fixed categorical labels to ensure representation of each category | ||
| fixed_labels = ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A'] | ||
| self.labels_categorical = pd.Series(fixed_labels, dtype="category") | ||
|
|
||
| def test_invalid_input_type(self): | ||
| """Test handling of invalid input types.""" | ||
| with self.assertRaises(ValueError) as context_manager: | ||
| heatmap_datashader(1, self.y, labels=self.labels_categorical) | ||
| self.assertIn("x and y must be array-like", | ||
| str(context_manager.exception)) | ||
|
|
||
| def test_labels_length_mismatch(self): | ||
| """Test handling of mismatched lengths between data and labels.""" | ||
| wrong_labels = pd.Series(['A'] * 9) # Shorter than x and y | ||
| with self.assertRaises(ValueError) as context_manager: | ||
| heatmap_datashader(self.x, self.y, labels=wrong_labels) | ||
| self.assertIn("Labels length should match x and y length", | ||
| str(context_manager.exception)) | ||
|
|
||
| def test_valid_input_returns_figure_basic(self): | ||
| """Test that valid input returns a matplotlib figure with expected subplots.""" | ||
| fig = heatmap_datashader(self.x, self.y, | ||
| labels=self.labels_categorical) | ||
| self.assertIsInstance(fig, matplotlib.figure.Figure) | ||
|
|
||
| num_axes = len(fig.axes) | ||
| expected_axes = self.labels_categorical.nunique() | ||
| self.assertEqual(num_axes, expected_axes) | ||
|
|
||
| def test_labels_not_multiple_of_three(self): | ||
| """Test heatmap generation when the number of labels is not a multiple of 3.""" | ||
| x = np.random.rand(7) | ||
| y = np.random.rand(7) | ||
| labels = pd.Series(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype="category") # 7 labels | ||
|
|
||
| fig = heatmap_datashader(x, y, labels=labels) | ||
| self.assertIsInstance(fig, matplotlib.figure.Figure) | ||
|
|
||
| num_axes = len(fig.axes) | ||
| expected_axes = labels.nunique() | ||
| self.assertEqual(num_axes, expected_axes) | ||
|
|
||
| for ax in fig.axes: | ||
| images = [child for child in ax.get_children() | ||
| if isinstance(child, matplotlib.image.AxesImage)] | ||
| self.assertGreater(len(images), 0, | ||
| "Expected at least one image in each subplot.") | ||
|
|
||
| def test_valid_input_returns_figure(self): | ||
| """Test that valid input returns a matplotlib figure with expected subplots and images.""" | ||
| fig = heatmap_datashader(self.x, self.y, | ||
| labels=self.labels_categorical) | ||
| self.assertIsInstance(fig, matplotlib.figure.Figure) | ||
|
|
||
| # Check number of axes matches number of unique labels | ||
| num_axes = len(fig.axes) | ||
| expected_axes = self.labels_categorical.nunique() | ||
| self.assertEqual(num_axes, expected_axes) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @LizaShch, any other assertion you can add to make sure the plot got generated correctly besides the number of axes? For example, the content of the plot? |
||
|
|
||
| # Check that each axis has an image plotted | ||
| for ax in fig.axes: | ||
| images = [child for child in ax.get_children() | ||
| if isinstance(child, matplotlib.image.AxesImage)] | ||
| self.assertGreater(len(images), 0, | ||
| "Expected at least one image in each subplot.") | ||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LizaShch, can we use kwargs to pass optional arguments to ds.Canvas to control the figure? This way, you don't need to explicty control only for plot width and plot height, but for all other input argument that function would tak.