Loading q2_feature_table/_heatmap/_visualizer.py +21 −5 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ heatmap_choices = { 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r', 'winter', 'winter_r'} 'winter', 'winter_r', 'cividis', 'cividis_r'} } Loading @@ -75,7 +75,7 @@ _clustering_map = {'both': {'col_cluster': True, 'row_cluster': True}, 'none': {'col_cluster': False, 'row_cluster': False}} def _munge_metadata(metadata, table, cluster): def _munge_sample_metadata(metadata, table, cluster): metadata = metadata.filter_ids(table.index) column_name = metadata.name Loading @@ -97,16 +97,32 @@ def _munge_metadata(metadata, table, cluster): return table def _munge_feature_metadata(metadata, table, cluster): metadata = metadata.filter_ids(table.columns) column_name = metadata.name metadata_df = metadata.to_dataframe() # replace feature IDs with feature metadata annotations table.columns = metadata_df.reindex(table.columns)[column_name].values if cluster == 'samples': table = table.sort_index(axis=1) return table def heatmap(output_dir, table: pd.DataFrame, metadata: qiime2.CategoricalMetadataColumn = None, sample_metadata: qiime2.CategoricalMetadataColumn = None, feature_metadata: qiime2.CategoricalMetadataColumn = None, normalize: bool = True, title: str = None, metric: str = 'euclidean', method: str = 'average', cluster: str = 'both', color_scheme: str = 'rocket') -> None: if table.empty: raise ValueError('Cannot visualize an empty table.') if metadata is not None: table = _munge_metadata(metadata, table, cluster) if sample_metadata is not None: table = _munge_sample_metadata(sample_metadata, table, cluster) # relabel feature table feature IDs with feature metadata column values if feature_metadata is not None: table = _munge_feature_metadata(feature_metadata, table, cluster) cbar_label = 'frequency' if normalize: Loading q2_feature_table/_version.py +3 −3 Original line number Diff line number Diff line Loading @@ -23,9 +23,9 @@ def get_keywords(): # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = " (tag: 2019.7.0)" git_full = "7e18386b0948bb436e76daf0d72691ba0dc636b9" git_date = "2019-07-30 18:15:52 +0000" git_refnames = " (tag: 2019.10.0)" git_full = "6cc22b63649fb3fc24855f1bdb8e4864c9e6081b" git_date = "2019-11-01 01:04:23 +0000" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords Loading q2_feature_table/plugin_setup.py +10 −4 Original line number Diff line number Diff line Loading @@ -440,7 +440,8 @@ plugin.visualizers.register_function( 'table': FeatureTable[Frequency] }, parameters={ 'metadata': MetadataColumn[Categorical], 'sample_metadata': MetadataColumn[Categorical], 'feature_metadata': MetadataColumn[Categorical], 'normalize': Bool, 'title': Str, 'metric': Str % Choices(q2_feature_table.heatmap_choices['metric']), Loading @@ -459,9 +460,14 @@ plugin.visualizers.register_function( 'table': 'The feature table to visualize.' }, parameter_descriptions={ 'metadata': 'Annotate the sample IDs with these metadata values. ' 'When metadata is present and `cluster`=\'feature\', ' 'samples will be sorted by the metadata values.', 'sample_metadata': 'Annotate the sample IDs with these sample ' 'metadata values. When metadata is present and ' '`cluster`=\'feature\', samples will be sorted by ' 'the metadata values.', 'feature_metadata': 'Annotate the feature IDs with these feature ' 'metadata values. When metadata is present and ' '`cluster`=\'sample\', features will be sorted by ' 'the metadata values.', 'normalize': 'Normalize the feature table by adding a psuedocount ' 'of 1 and then taking the log10 of the table.', 'title': 'Optional custom plot title.', Loading q2_feature_table/tests/test_heatmap.py +104 −16 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ from pandas.testing import assert_frame_equal import qiime2 from q2_feature_table import heatmap from q2_feature_table._heatmap._visualizer import _munge_metadata from q2_feature_table._heatmap._visualizer import ( _munge_sample_metadata, _munge_feature_metadata) class TestHeatmap(unittest.TestCase): Loading Loading @@ -59,7 +60,27 @@ class TestHeatmap(unittest.TestCase): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) heatmap(self.output_dir, self.table, metadata=md) heatmap(self.output_dir, self.table, sample_metadata=md) self.assertBasicVizValidity(self.output_dir) def test_with_feature_metadata(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) heatmap(self.output_dir, self.table, feature_metadata=feature_md) self.assertBasicVizValidity(self.output_dir) def test_with_sample_and_feature_metadata(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) heatmap(self.output_dir, self.table, sample_metadata=md, feature_metadata=feature_md) self.assertBasicVizValidity(self.output_dir) Loading @@ -75,14 +96,14 @@ class TestHeatmap(unittest.TestCase): index=pd.Index(['S1', 'S3'], name='id'))) with self.assertRaisesRegex(ValueError, 'not present.*S2'): heatmap(self.output_dir, self.table, metadata=md) heatmap(self.output_dir, self.table, sample_metadata=md) def test_extra_metadata_ids(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'summer', 'russ', 'peanut'], name='pet', index=pd.Index(['S1', 'S2', 'S3', 'S4'], name='id'))) heatmap(self.output_dir, self.table, metadata=md) heatmap(self.output_dir, self.table, sample_metadata=md) self.assertBasicVizValidity(self.output_dir) Loading @@ -96,7 +117,8 @@ class TestHeatmap(unittest.TestCase): pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) heatmap(self.output_dir, self.table, metadata=md, cluster='features') heatmap(self.output_dir, self.table, sample_metadata=md, cluster='features') self.assertBasicVizValidity(self.output_dir) Loading @@ -105,7 +127,8 @@ class TestHeatmap(unittest.TestCase): pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) heatmap(self.output_dir, self.table, metadata=md, cluster='none') heatmap(self.output_dir, self.table, sample_metadata=md, cluster='none') self.assertBasicVizValidity(self.output_dir) Loading @@ -116,11 +139,11 @@ class TestPrivateHelpers(unittest.TestCase): columns=['O1', 'O2'], index=['S1', 'S2', 'S3']) def test_munge_metadata_simple(self): def test_munge_sample_metadata_simple(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'russ', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'both') obs = _munge_sample_metadata(md, self.table, 'both') exp_idx = pd.Index(['milo | S1', 'russ | S2', 'russ | S3'], name='pet | id') Loading @@ -128,11 +151,11 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_metadata_ids_different_order(self): def test_munge_sample_metadata_ids_different_order(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['russ', 'milo', 'russ'], name='pet', index=pd.Index(['S2', 'S1', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'both') obs = _munge_sample_metadata(md, self.table, 'both') exp_idx = pd.Index(['milo | S1', 'russ | S2', 'russ | S3'], name='pet | id') Loading @@ -140,18 +163,18 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_metadata_missing_samples(self): def test_munge_sample_metadata_missing_samples(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'russ'], name='pet', index=pd.Index(['S1', 'S3'], name='id'))) with self.assertRaisesRegex(ValueError, 'not present.*S2'): _munge_metadata(md, self.table, 'both') _munge_sample_metadata(md, self.table, 'both') def test_munge_metadata_empty_values(self): def test_munge_sample_metadata_empty_values(self): md = qiime2.CategoricalMetadataColumn( pd.Series([None, 'russ', np.nan], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'both') obs = _munge_sample_metadata(md, self.table, 'both') exp_idx = pd.Index(['[No Value] | S1', 'russ | S2', '[No Value] | S3'], name='pet | id') Loading @@ -159,11 +182,11 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_metadata_sort_samples(self): def test_munge_sample_metadata_sort_samples(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'milo', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'features') obs = _munge_sample_metadata(md, self.table, 'features') exp_idx = pd.Index(['milo | S2', 'peanut | S1', 'russ | S3'], name='pet | id') Loading @@ -171,6 +194,71 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_feature_metadata_simple(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'both') exp = pd.DataFrame( [[0, 10], [10, 12], [10, 11]], columns=['peanut', 'dog'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_ids_different_order(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['dog', 'peanut'], name='species', index=pd.Index(['O2', 'O1'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'both') exp = pd.DataFrame( [[0, 10], [10, 12], [10, 11]], columns=['peanut', 'dog'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_missing_features(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series( ['dog'], name='species', index=pd.Index(['O2'], name='id'))) with self.assertRaisesRegex(ValueError, 'not present.*O1'): _munge_feature_metadata(feature_md, self.table, 'both') def test_munge_feature_metadata_is_superset(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog', 'cujo'], name='species', index=pd.Index(['O1', 'O2', 'O3'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'both') exp = pd.DataFrame( [[0, 10], [10, 12], [10, 11]], columns=['peanut', 'dog'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_sort_samples(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'samples') exp = pd.DataFrame( [[10, 0], [12, 10], [11, 10]], columns=['dog', 'peanut'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_sort_duplicate_feature_names(self): new_tab = self.table.copy() new_tab['O3'] = [1, 2, 3] feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog', 'peanut'], name='species', index=pd.Index(['O1', 'O2', 'O3'], name='id'))) obs = _munge_feature_metadata(feature_md, new_tab, 'samples') exp = pd.DataFrame( [[10, 0, 1], [12, 10, 2], [11, 10, 3]], columns=['dog', 'peanut', 'peanut'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) if __name__ == "__main__": unittest.main() Loading
q2_feature_table/_heatmap/_visualizer.py +21 −5 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ heatmap_choices = { 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r', 'winter', 'winter_r'} 'winter', 'winter_r', 'cividis', 'cividis_r'} } Loading @@ -75,7 +75,7 @@ _clustering_map = {'both': {'col_cluster': True, 'row_cluster': True}, 'none': {'col_cluster': False, 'row_cluster': False}} def _munge_metadata(metadata, table, cluster): def _munge_sample_metadata(metadata, table, cluster): metadata = metadata.filter_ids(table.index) column_name = metadata.name Loading @@ -97,16 +97,32 @@ def _munge_metadata(metadata, table, cluster): return table def _munge_feature_metadata(metadata, table, cluster): metadata = metadata.filter_ids(table.columns) column_name = metadata.name metadata_df = metadata.to_dataframe() # replace feature IDs with feature metadata annotations table.columns = metadata_df.reindex(table.columns)[column_name].values if cluster == 'samples': table = table.sort_index(axis=1) return table def heatmap(output_dir, table: pd.DataFrame, metadata: qiime2.CategoricalMetadataColumn = None, sample_metadata: qiime2.CategoricalMetadataColumn = None, feature_metadata: qiime2.CategoricalMetadataColumn = None, normalize: bool = True, title: str = None, metric: str = 'euclidean', method: str = 'average', cluster: str = 'both', color_scheme: str = 'rocket') -> None: if table.empty: raise ValueError('Cannot visualize an empty table.') if metadata is not None: table = _munge_metadata(metadata, table, cluster) if sample_metadata is not None: table = _munge_sample_metadata(sample_metadata, table, cluster) # relabel feature table feature IDs with feature metadata column values if feature_metadata is not None: table = _munge_feature_metadata(feature_metadata, table, cluster) cbar_label = 'frequency' if normalize: Loading
q2_feature_table/_version.py +3 −3 Original line number Diff line number Diff line Loading @@ -23,9 +23,9 @@ def get_keywords(): # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = " (tag: 2019.7.0)" git_full = "7e18386b0948bb436e76daf0d72691ba0dc636b9" git_date = "2019-07-30 18:15:52 +0000" git_refnames = " (tag: 2019.10.0)" git_full = "6cc22b63649fb3fc24855f1bdb8e4864c9e6081b" git_date = "2019-11-01 01:04:23 +0000" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords Loading
q2_feature_table/plugin_setup.py +10 −4 Original line number Diff line number Diff line Loading @@ -440,7 +440,8 @@ plugin.visualizers.register_function( 'table': FeatureTable[Frequency] }, parameters={ 'metadata': MetadataColumn[Categorical], 'sample_metadata': MetadataColumn[Categorical], 'feature_metadata': MetadataColumn[Categorical], 'normalize': Bool, 'title': Str, 'metric': Str % Choices(q2_feature_table.heatmap_choices['metric']), Loading @@ -459,9 +460,14 @@ plugin.visualizers.register_function( 'table': 'The feature table to visualize.' }, parameter_descriptions={ 'metadata': 'Annotate the sample IDs with these metadata values. ' 'When metadata is present and `cluster`=\'feature\', ' 'samples will be sorted by the metadata values.', 'sample_metadata': 'Annotate the sample IDs with these sample ' 'metadata values. When metadata is present and ' '`cluster`=\'feature\', samples will be sorted by ' 'the metadata values.', 'feature_metadata': 'Annotate the feature IDs with these feature ' 'metadata values. When metadata is present and ' '`cluster`=\'sample\', features will be sorted by ' 'the metadata values.', 'normalize': 'Normalize the feature table by adding a psuedocount ' 'of 1 and then taking the log10 of the table.', 'title': 'Optional custom plot title.', Loading
q2_feature_table/tests/test_heatmap.py +104 −16 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ from pandas.testing import assert_frame_equal import qiime2 from q2_feature_table import heatmap from q2_feature_table._heatmap._visualizer import _munge_metadata from q2_feature_table._heatmap._visualizer import ( _munge_sample_metadata, _munge_feature_metadata) class TestHeatmap(unittest.TestCase): Loading Loading @@ -59,7 +60,27 @@ class TestHeatmap(unittest.TestCase): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) heatmap(self.output_dir, self.table, metadata=md) heatmap(self.output_dir, self.table, sample_metadata=md) self.assertBasicVizValidity(self.output_dir) def test_with_feature_metadata(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) heatmap(self.output_dir, self.table, feature_metadata=feature_md) self.assertBasicVizValidity(self.output_dir) def test_with_sample_and_feature_metadata(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) heatmap(self.output_dir, self.table, sample_metadata=md, feature_metadata=feature_md) self.assertBasicVizValidity(self.output_dir) Loading @@ -75,14 +96,14 @@ class TestHeatmap(unittest.TestCase): index=pd.Index(['S1', 'S3'], name='id'))) with self.assertRaisesRegex(ValueError, 'not present.*S2'): heatmap(self.output_dir, self.table, metadata=md) heatmap(self.output_dir, self.table, sample_metadata=md) def test_extra_metadata_ids(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'summer', 'russ', 'peanut'], name='pet', index=pd.Index(['S1', 'S2', 'S3', 'S4'], name='id'))) heatmap(self.output_dir, self.table, metadata=md) heatmap(self.output_dir, self.table, sample_metadata=md) self.assertBasicVizValidity(self.output_dir) Loading @@ -96,7 +117,8 @@ class TestHeatmap(unittest.TestCase): pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) heatmap(self.output_dir, self.table, metadata=md, cluster='features') heatmap(self.output_dir, self.table, sample_metadata=md, cluster='features') self.assertBasicVizValidity(self.output_dir) Loading @@ -105,7 +127,8 @@ class TestHeatmap(unittest.TestCase): pd.Series(['milo', 'summer', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) heatmap(self.output_dir, self.table, metadata=md, cluster='none') heatmap(self.output_dir, self.table, sample_metadata=md, cluster='none') self.assertBasicVizValidity(self.output_dir) Loading @@ -116,11 +139,11 @@ class TestPrivateHelpers(unittest.TestCase): columns=['O1', 'O2'], index=['S1', 'S2', 'S3']) def test_munge_metadata_simple(self): def test_munge_sample_metadata_simple(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'russ', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'both') obs = _munge_sample_metadata(md, self.table, 'both') exp_idx = pd.Index(['milo | S1', 'russ | S2', 'russ | S3'], name='pet | id') Loading @@ -128,11 +151,11 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_metadata_ids_different_order(self): def test_munge_sample_metadata_ids_different_order(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['russ', 'milo', 'russ'], name='pet', index=pd.Index(['S2', 'S1', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'both') obs = _munge_sample_metadata(md, self.table, 'both') exp_idx = pd.Index(['milo | S1', 'russ | S2', 'russ | S3'], name='pet | id') Loading @@ -140,18 +163,18 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_metadata_missing_samples(self): def test_munge_sample_metadata_missing_samples(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['milo', 'russ'], name='pet', index=pd.Index(['S1', 'S3'], name='id'))) with self.assertRaisesRegex(ValueError, 'not present.*S2'): _munge_metadata(md, self.table, 'both') _munge_sample_metadata(md, self.table, 'both') def test_munge_metadata_empty_values(self): def test_munge_sample_metadata_empty_values(self): md = qiime2.CategoricalMetadataColumn( pd.Series([None, 'russ', np.nan], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'both') obs = _munge_sample_metadata(md, self.table, 'both') exp_idx = pd.Index(['[No Value] | S1', 'russ | S2', '[No Value] | S3'], name='pet | id') Loading @@ -159,11 +182,11 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_metadata_sort_samples(self): def test_munge_sample_metadata_sort_samples(self): md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'milo', 'russ'], name='pet', index=pd.Index(['S1', 'S2', 'S3'], name='id'))) obs = _munge_metadata(md, self.table, 'features') obs = _munge_sample_metadata(md, self.table, 'features') exp_idx = pd.Index(['milo | S2', 'peanut | S1', 'russ | S3'], name='pet | id') Loading @@ -171,6 +194,71 @@ class TestPrivateHelpers(unittest.TestCase): index=exp_idx) assert_frame_equal(exp, obs) def test_munge_feature_metadata_simple(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'both') exp = pd.DataFrame( [[0, 10], [10, 12], [10, 11]], columns=['peanut', 'dog'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_ids_different_order(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['dog', 'peanut'], name='species', index=pd.Index(['O2', 'O1'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'both') exp = pd.DataFrame( [[0, 10], [10, 12], [10, 11]], columns=['peanut', 'dog'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_missing_features(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series( ['dog'], name='species', index=pd.Index(['O2'], name='id'))) with self.assertRaisesRegex(ValueError, 'not present.*O1'): _munge_feature_metadata(feature_md, self.table, 'both') def test_munge_feature_metadata_is_superset(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog', 'cujo'], name='species', index=pd.Index(['O1', 'O2', 'O3'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'both') exp = pd.DataFrame( [[0, 10], [10, 12], [10, 11]], columns=['peanut', 'dog'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_sort_samples(self): feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog'], name='species', index=pd.Index(['O1', 'O2'], name='id'))) obs = _munge_feature_metadata(feature_md, self.table, 'samples') exp = pd.DataFrame( [[10, 0], [12, 10], [11, 10]], columns=['dog', 'peanut'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) def test_munge_feature_metadata_sort_duplicate_feature_names(self): new_tab = self.table.copy() new_tab['O3'] = [1, 2, 3] feature_md = qiime2.CategoricalMetadataColumn( pd.Series(['peanut', 'dog', 'peanut'], name='species', index=pd.Index(['O1', 'O2', 'O3'], name='id'))) obs = _munge_feature_metadata(feature_md, new_tab, 'samples') exp = pd.DataFrame( [[10, 0, 1], [12, 10, 2], [11, 10, 3]], columns=['dog', 'peanut', 'peanut'], index=pd.Index(['S1', 'S2', 'S3'])) assert_frame_equal(exp, obs) if __name__ == "__main__": unittest.main()