diff --git a/README.md b/README.md index 1277b27..68d626c 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,12 @@ Developers, please make pull requests to the https://github.com/elmbeech/physice + evt generate lineage tree graph output files. ## Release Notes: ++ version 4.0.5 (2025-10-22): elmbeech/physicelldataloader + + **settingxml** default is now set to False, because the cell\_type id label mapping can, in recent PhysiCell output, be retrieved from output\*.xml too. + + **plot_scatter** and **plot_timeseries** now additionally have a cat\_drop and cat\_keep argument to filter categorical data. + + **plot_timeseries(frame=conc)** now plots by default all substrate concentrations over time. + + **plot_timeseries(ext=)** parameter offers to return a dataframe object, dafaframe csv file, image file, or a matplotlib fig object. special thanks to John Nardini and Edward Young. + + version 4.0.4 (2025-07-23): elmbeech/physicelldataloader + command line commands now return **error code 0** if the command runs successfully. diff --git a/man/TUTORIAL_python3_graph.md b/man/TUTORIAL_python3_graph.md index 4f31bef..c77a283 100644 --- a/man/TUTORIAL_python3_graph.md +++ b/man/TUTORIAL_python3_graph.md @@ -45,7 +45,7 @@ print(sorted(g.nodes.keys())[0:4]) print(sorted(g.edges.keys())[0:4]) ``` ```python -g.nodes['node_0'] # {'cell_type': 'cancer_cell', 'dead': 0, 'oxygen': 25.304510426523084, 'pressure': 10.519314516003435} +g.nodes['node_0'] # {'cell_type': 'default', 'dead': 0, 'oxygen': 25.304510426523084, 'pressure': 10.519314516003435} ``` ```python g.edges[('node_0', 'node_1')] # {'label': 'edge_0_1', 'distance_microns': 15} diff --git a/man/TUTORIAL_python3_ometiff.md b/man/TUTORIAL_python3_ometiff.md index 1dc2d61..22d7624 100644 --- a/man/TUTORIAL_python3_ometiff.md +++ b/man/TUTORIAL_python3_ometiff.md @@ -77,7 +77,7 @@ img.shape # (25, 2, 1, 200, 300) img.dims # ``` ```python -img.channel_names # [np.str_('oxygen'), np.str_('cancer_cell')] +img.channel_names # [np.str_('oxygen'), np.str_('default')] ``` That's it. The rest is analysis! diff --git a/man/TUTORIAL_python3_timestep.md b/man/TUTORIAL_python3_timestep.md index 0f58a4f..1cc258c 100644 --- a/man/TUTORIAL_python3_timestep.md +++ b/man/TUTORIAL_python3_timestep.md @@ -241,13 +241,13 @@ We can retrieve a list of all cell types processed in the simulation, ordered by cell type ID. ```python -mcds.get_celltype_list() # ['cancer_cell'] +mcds.get_celltype_list() # ['default'] ``` We can retrieve a dictionary that maps cell type IDs to labels. ```python -mcds.get_celltype_dict() # {'0': 'cancer_cell'} +mcds.get_celltype_dict() # {'0': 'default'} ``` And we can retrieve an alphabetically ordered list with all cell agent attributes outputted by PhysiCell, loadable with mcds.get\_cell\_df(). diff --git a/man/docstring/mcds.__init__.md b/man/docstring/mcds.__init__.md index f760d95..33c7f1c 100644 --- a/man/docstring/mcds.__init__.md +++ b/man/docstring/mcds.__init__.md @@ -29,7 +29,7 @@ should physiboss state data be loaded, if found? setting physiboss to False will use less memory and speed up processing. - settingxml: string; default PhysiCell_settings.xml + settingxml: string; default False the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. diff --git a/man/docstring/mcds.plot_scatter.md b/man/docstring/mcds.plot_scatter.md index 332fbbd..37f9d31 100644 --- a/man/docstring/mcds.plot_scatter.md +++ b/man/docstring/mcds.plot_scatter.md @@ -6,6 +6,16 @@ focus: string; default is 'cell_type' column name within cell dataframe. + cat_drop: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be dropped for the dataframe. + Attention: when the cat_keep parameter is given, then + the cat_drop parameter has to be an empty set! + + cat_keep: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be kept in the dataframe. + z_slice: floating point number; default is 0.0 z-axis position to slice a 2D xy-plain out of the 3D substrate concentration mesh. if z_slice position diff --git a/man/docstring/mcdsts.__init__.md b/man/docstring/mcdsts.__init__.md index fade05a..283d202 100644 --- a/man/docstring/mcdsts.__init__.md +++ b/man/docstring/mcdsts.__init__.md @@ -29,7 +29,7 @@ should physiboss state data be loaded, if found? setting physiboss to False will use less memory and speed up processing. - settingxml: string; default PhysiCell_settings.xml + settingxml: string; default False the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. diff --git a/man/docstring/mcdsts.plot_scatter.md b/man/docstring/mcdsts.plot_scatter.md index f284c0d..43731cd 100644 --- a/man/docstring/mcdsts.plot_scatter.md +++ b/man/docstring/mcdsts.plot_scatter.md @@ -8,6 +8,16 @@ focus: string; default is 'cell_type' column name within cell dataframe. + cat_drop: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be dropped for the dataframe. + Attention: when the cat_keep parameter is given, then + the cat_drop parameter has to be an empty set! + + cat_keep: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be kept in the dataframe. + z_slice: floating point number; default is 0.0 z-axis position to slice a 2D xy-plain out of the 3D mesh. if z_slice position is not an exact mesh center coordinate, diff --git a/man/docstring/mcdsts.plot_timeseries.md b/man/docstring/mcdsts.plot_timeseries.md index 09385d5..d226baa 100644 --- a/man/docstring/mcdsts.plot_timeseries.md +++ b/man/docstring/mcdsts.plot_timeseries.md @@ -21,6 +21,16 @@ cell: dataframe will be retrieved through the mcds.get_cell_df function. conc: dataframe will be retrieved through the mcds.get_conc_df function. + cat_drop: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be dropped for the dataframe. + Attention: when the cat_keep parameter is given, then + the cat_drop parameter has to be an empty set! + + cat_keep: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be kept in the dataframe. + z_slice: floating point number; default is None z-axis position to slice a 2D xy-plain out of the 3D mesh. if z_slice position numeric but not an exact mesh center coordinate, @@ -92,14 +102,16 @@ to be able to generate movies from the images. ext: string; default is None - output image format. possible formats are None, jpeg, png, and tiff. - if None then the matplotlib figure is returned by the function - and not written to file. + output format. + possible image formats are jpeg, jpg, png, tif, and tiff. + for retrieving a datafarme file use csv. + any other string or a number returns a pandas dataframe object. + None returnes a matplotlib figure object. figbgcolor: string; default is None which is transparent (png) or white (jpeg, tiff). figure background color. - only relevant if ext not is None. + only relevant if ext specifies an image file. **kwargs: possible additional keyword arguments input, handled by the pandas series plot function. diff --git a/man/docstring/pcdl_get_anndata.md b/man/docstring/pcdl_get_anndata.md index cb59d2f..8a40978 100644 --- a/man/docstring/pcdl_get_anndata.md +++ b/man/docstring/pcdl_get_anndata.md @@ -41,7 +41,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_get_cell_attribute.md b/man/docstring/pcdl_get_cell_attribute.md index 2b1eb98..5e8327c 100644 --- a/man/docstring/pcdl_get_cell_attribute.md +++ b/man/docstring/pcdl_get_cell_attribute.md @@ -43,7 +43,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_get_cell_attribute_list.md b/man/docstring/pcdl_get_cell_attribute_list.md index 8acf2f2..07cacf7 100644 --- a/man/docstring/pcdl_get_cell_attribute_list.md +++ b/man/docstring/pcdl_get_cell_attribute_list.md @@ -24,7 +24,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to True for more text output, while processing. default is False. diff --git a/man/docstring/pcdl_get_cell_df.md b/man/docstring/pcdl_get_cell_df.md index 2b31c79..f72a5dd 100644 --- a/man/docstring/pcdl_get_cell_df.md +++ b/man/docstring/pcdl_get_cell_df.md @@ -29,7 +29,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_get_celltype_list.md b/man/docstring/pcdl_get_celltype_list.md index 683c59b..c4b044d 100644 --- a/man/docstring/pcdl_get_celltype_list.md +++ b/man/docstring/pcdl_get_celltype_list.md @@ -16,7 +16,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to True for more text output, while processing. default is False. diff --git a/man/docstring/pcdl_get_unit_dict.md b/man/docstring/pcdl_get_unit_dict.md index 710b081..5491572 100644 --- a/man/docstring/pcdl_get_unit_dict.md +++ b/man/docstring/pcdl_get_unit_dict.md @@ -19,7 +19,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_make_cell_vtk.md b/man/docstring/pcdl_make_cell_vtk.md index 0043ac5..8c8e335 100644 --- a/man/docstring/pcdl_make_cell_vtk.md +++ b/man/docstring/pcdl_make_cell_vtk.md @@ -35,7 +35,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_make_graph_gml.md b/man/docstring/pcdl_make_graph_gml.md index c47ebf9..0e27227 100644 --- a/man/docstring/pcdl_make_graph_gml.md +++ b/man/docstring/pcdl_make_graph_gml.md @@ -43,7 +43,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_make_ome_tiff.md b/man/docstring/pcdl_make_ome_tiff.md index 50e7d6c..91de7dd 100644 --- a/man/docstring/pcdl_make_ome_tiff.md +++ b/man/docstring/pcdl_make_ome_tiff.md @@ -32,7 +32,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. diff --git a/man/docstring/pcdl_plot_scatter.md b/man/docstring/pcdl_plot_scatter.md index b97563b..65447fb 100644 --- a/man/docstring/pcdl_plot_scatter.md +++ b/man/docstring/pcdl_plot_scatter.md @@ -2,11 +2,12 @@ usage: pcdl_plot_scatter [-h] [--custom_data_type [CUSTOM_DATA_TYPE ...]] [--microenv MICROENV] [--physiboss PHYSIBOSS] [--settingxml SETTINGXML] [-v VERBOSE] - [--z_slice Z_SLICE] [--z_axis Z_AXIS [Z_AXIS ...]] - [--alpha ALPHA] [--cmap CMAP] [--title TITLE] - [--grid GRID] [--legend_loc LEGEND_LOC] - [--xlim XLIM [XLIM ...]] [--ylim YLIM [YLIM ...]] - [--xyequal XYEQUAL] [--s S] + [--cat_drop [CAT_DROP ...]] + [--cat_keep [CAT_KEEP ...]] [--z_slice Z_SLICE] + [--z_axis Z_AXIS [Z_AXIS ...]] [--alpha ALPHA] + [--cmap CMAP] [--title TITLE] [--grid GRID] + [--legend_loc LEGEND_LOC] [--xlim XLIM [XLIM ...]] + [--ylim YLIM [YLIM ...]] [--xyequal XYEQUAL] [--s S] [--figsizepx FIGSIZEPX [FIGSIZEPX ...]] [--ext EXT] [--figbgcolor FIGBGCOLOR] [path] [focus] @@ -39,10 +40,20 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. + --cat_drop [CAT_DROP ...] + if focus is a categorical attribute, set of category + labels, strings separated by space, to be dropped for + the dataframe. Attention: when the cat_keep parameter + is given, then the cat_drop parameter has to be an + empty string! default is an empty string. + --cat_keep [CAT_KEEP ...] + if focus is a categorical attribute, set of category + labels, strings separated by space, to be kept in the + dataframe. default is an empty string. --z_slice Z_SLICE z-axis position to slice a 2D xy-plain out of the 3D mesh. if z_slice position numeric but not an exact mesh center coordinate, then z_slice will be adjusted diff --git a/man/docstring/pcdl_plot_timeseries.md b/man/docstring/pcdl_plot_timeseries.md index e93a2ca..e617c6e 100644 --- a/man/docstring/pcdl_plot_timeseries.md +++ b/man/docstring/pcdl_plot_timeseries.md @@ -2,8 +2,9 @@ usage: pcdl_plot_timeseries [-h] [--custom_data_type [CUSTOM_DATA_TYPE ...]] [--microenv MICROENV] [--physiboss PHYSIBOSS] [--settingxml SETTINGXML] [-v VERBOSE] - [--frame FRAME] [--z_slice Z_SLICE] [--logy LOGY] - [--ylim YLIM [YLIM ...]] + [--frame FRAME] [--cat_drop [CAT_DROP ...]] + [--cat_keep [CAT_KEEP ...]] [--z_slice Z_SLICE] + [--logy LOGY] [--ylim YLIM [YLIM ...]] [--secondary_y SECONDARY_Y [SECONDARY_Y ...]] [--subplots SUBPLOTS] [--sharex SHAREX] [--sharey SHAREY] [--linestyle LINESTYLE] @@ -49,7 +50,7 @@ options: type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default - is PhysiCell_settings.xml. + is False. -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. @@ -57,6 +58,16 @@ options: be retrieved through the mcds.get_cell_df function. conc: dataframe will be retrieved through the mcds.get_conc_df function. default is cell. + --cat_drop [CAT_DROP ...] + if focus is a categorical attribute, set of category + labels to be dropped for the dataframe. Attention: + when the cat_keep parameter is given, then the + cat_drop parameter has to be an empty string! default + is an empty string. + --cat_keep [CAT_KEEP ...] + if focus is a categorical attribute, set of category + labels to be kept in the dataframe. default is an + empty string. --z_slice Z_SLICE z-axis position to slice a 2D xy-plain out of the 3D mesh. if z_slice position numeric but not an exact mesh center coordinate, then z_slice will be adjusted @@ -84,7 +95,7 @@ options: matplotlib line style {-, --, .-, :} string. default is - . --linewidth LINEWIDTH - line width in points, integer. default is None. + line width in points, float. default is None. --cmap CMAP matplotlib colormap string from https://matplotlib.org /stable/tutorials/colors/colormaps.html . default is None. @@ -103,8 +114,9 @@ options: x and y will be rounded to the nearest even number, to be able to generate movies from the images. default is 640 480. - --ext EXT output image format. possible formats are jpeg, png, - and tiff. default is jpeg. + --ext EXT output format. possible image formats are jpeg, jpg, + png, tif, and tiff. for retrieving a datafarme file + use csv. default is jpeg. --figbgcolor FIGBGCOLOR figure background color. None is transparent (png) or white (jpeg, tiff). default is None. diff --git a/pcdl/VERSION.py b/pcdl/VERSION.py index d5f9f2a..02c2261 100644 --- a/pcdl/VERSION.py +++ b/pcdl/VERSION.py @@ -1 +1 @@ -__version__ = '4.0.4' +__version__ = '4.0.5' diff --git a/pcdl/commandline.py b/pcdl/commandline.py index f77ec5e..079449b 100644 --- a/pcdl/commandline.py +++ b/pcdl/commandline.py @@ -130,8 +130,8 @@ def get_unit_dict(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -807,8 +807,8 @@ def get_celltype_list(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -884,8 +884,8 @@ def get_cell_attribute_list(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -967,8 +967,8 @@ def get_cell_attribute(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -1118,8 +1118,8 @@ def get_cell_df(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -1274,8 +1274,8 @@ def get_anndata(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -1445,8 +1445,8 @@ def make_graph_gml(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -1586,8 +1586,8 @@ def plot_scatter(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -1602,6 +1602,20 @@ def plot_scatter(): default = 'cell_type', help = 'column name within conc dataframe. default is cell_type.', ) + # plot_scatter cat_drop + parser.add_argument( + '--cat_drop', + nargs = '*', + default = [], + help = "if focus is a categorical attribute, set of category labels, strings separated by space, to be dropped for the dataframe. Attention: when the cat_keep parameter is given, then the cat_drop parameter has to be an empty string! default is an empty string.", + ) + # plot_scatter cat_keep + parser.add_argument( + '--cat_keep', + nargs = '*', + default = [], + help = "if focus is a categorical attribute, set of category labels, strings separated by space, to be kept in the dataframe. default is an empty string.", + ) # plot_scatter z_slice parser.add_argument( '--z_slice', @@ -1740,6 +1754,8 @@ def plot_scatter(): # plot s_opathfile = mcds.plot_scatter( focus = args.focus, + cat_drop = set(args.cat_drop), + cat_keep = set(args.cat_keep), z_slice = args.z_slice, z_axis = None if (args.z_axis[0].lower() == 'none') else args.z_axis, alpha = args.alpha, @@ -1773,6 +1789,8 @@ def plot_scatter(): # plot ls_opathfile = mcdsts.plot_scatter( focus = args.focus, + cat_drop = set(args.cat_drop), + cat_keep = set(args.cat_keep), z_slice = args.z_slice, z_axis = None if (args.z_axis[0].lower() == 'none') else args.z_axis, alpha = args.alpha, @@ -1835,8 +1853,8 @@ def make_cell_vtk(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -1964,8 +1982,8 @@ def plot_timeseries(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( @@ -2000,6 +2018,21 @@ def plot_timeseries(): default = 'cell', help = 'to specifies the data dataframe. cell: dataframe will be retrieved through the mcds.get_cell_df function. conc: dataframe will be retrieved through the mcds.get_conc_df function. default is cell.', ) + + # plot_timeseries cat_drop + parser.add_argument( + '--cat_drop', + nargs = '*', + default = [], + help = "if focus is a categorical attribute, set of category labels to be dropped for the dataframe. Attention: when the cat_keep parameter is given, then the cat_drop parameter has to be an empty string! default is an empty string.", + ) + # plot_timeseries cat_keep + parser.add_argument( + '--cat_keep', + nargs = '*', + default = [], + help = "if focus is a categorical attribute, set of category labels to be kept in the dataframe. default is an empty string.", + ) # plot_timeseries z_slice parser.add_argument( '--z_slice', @@ -2055,7 +2088,7 @@ def plot_timeseries(): parser.add_argument( '--linewidth', default = 'none', - help = 'line width in points, integer. default is None.', + help = 'line width in points, float. default is None.', ) # plot_timeseries cmap parser.add_argument( @@ -2109,7 +2142,7 @@ def plot_timeseries(): parser.add_argument( '--ext', default = 'jpeg', - help = 'output image format. possible formats are jpeg, png, and tiff. default is jpeg.', + help = 'output format. possible image formats are jpeg, jpg, png, tif, and tiff. for retrieving a datafarme file use csv. default is jpeg.', ) # plot_timeseries figbgcolor parser.add_argument( @@ -2182,6 +2215,8 @@ def plot_timeseries(): focus_num = None if (args.focus_num.lower() == 'none') else args.focus_num, aggregate_num = o_aggregate_num, frame = args.frame, + cat_drop = set(args.cat_drop), + cat_keep = set(args.cat_keep), z_slice = None if (args.z_slice.lower() == 'none') else float(args.z_slice), logy = True if args.logy.lower().startswith('t') else False, ylim = None if (args.ylim[0].lower() == 'none') else [float(y) for y in args.ylim], @@ -2190,7 +2225,7 @@ def plot_timeseries(): sharex = True if args.sharex.lower().startswith('t') else False, sharey = True if args.sharey.lower().startswith('t') else False, linestyle = args.linestyle, - linewidth = None if (args.linewidth.lower() == 'none') else int(args.linewidth), + linewidth = None if (args.linewidth.lower() == 'none') else float(args.linewidth), cmap = None if (args.cmap.lower() == 'none') else args.cmap, color = None if (args.color[0].lower() == 'none') else args.color, grid = False if args.grid.lower().startswith('f') else True, @@ -2240,8 +2275,8 @@ def make_ome_tiff(): # TimeSeries settingxml parser.add_argument( '--settingxml', - default = 'PhysiCell_settings.xml', - help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is PhysiCell_settings.xml.', + default = 'false', + help = 'the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. set to None or False if the xml file is missing! default is False.', ) # TimeSeries verbose parser.add_argument( diff --git a/pcdl/timeseries.py b/pcdl/timeseries.py index b3d1ae3..d4956ae 100644 --- a/pcdl/timeseries.py +++ b/pcdl/timeseries.py @@ -146,7 +146,7 @@ def make_movie(path, interface='jpeg', framerate=12): f.close() # genearete movie - s_cmd = f'ffmpeg -y -r {framerate} -f concat -i ffmpeginput.txt -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none "{s_ofile}"' # -safe 0 + s_cmd = f'ffmpeg -f concat -i ffmpeginput.txt -y -r {framerate} -pix_fmt yuv420p -strict -2 -codec:v h264 -tune animation -crf 15 -codec:a none "{s_ofile}"' # -safe 0 if (os.system(s_cmd) != 0): sys.exit("Error @ make_movie : ffmpeg could not generatet the movie.") os.remove('ffmpeginput.txt') @@ -161,7 +161,7 @@ def make_movie(path, interface='jpeg', framerate=12): ########### class TimeSeries: - def __init__(self, output_path='.', custom_data_type={}, load=True, microenv=True, graph=True, physiboss=True, settingxml='PhysiCell_settings.xml', verbose=True): + def __init__(self, output_path='.', custom_data_type={}, load=True, microenv=True, graph=True, physiboss=True, settingxml=False, verbose=True): """ input: output_path: string, default '.' @@ -190,7 +190,7 @@ def __init__(self, output_path='.', custom_data_type={}, load=True, microenv=Tru should physiboss state data be loaded, if found? setting physiboss to False will use less memory and speed up processing. - settingxml: string; default PhysiCell_settings.xml + settingxml: string; default False the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. @@ -214,9 +214,12 @@ def __init__(self, output_path='.', custom_data_type={}, load=True, microenv=Tru if (output_path.endswith('/')) and (len(output_path) > 1): output_path = output_path[:-1] if not os.path.isdir(output_path): - print(f'Error @ TimeSeries.__init__ : this is not a path! could not load {output_path}.') + sys.exit(f'Error @ TimeSeries.__init__ : this is not a path! could not load {output_path}.') self.path = output_path - self.ls_xmlfile = [s_pathfile.replace('\\','/').split('/')[-1] for s_pathfile in sorted(glob.glob(self.path + f'/output*.xml'))] # bue 2022-10-22: is output*.xml always the correct pattern? + # bue 2022-10-22: is output*.xml always the correct pattern? i could add initial or final step. + self.ls_xmlfile = [s_pathfile.replace('\\','/').split('/')[-1] for s_pathfile in sorted(glob.glob(self.path + f'/output*.xml'))] + if (len(self.ls_xmlfile) == 0): + sys.exit(f'Error @ TimeSeries.__init__ : could not detect any output*.xml! is the given output_path correct? {output_path}') self.custom_data_type = custom_data_type self.microenv = microenv self.graph = graph @@ -851,7 +854,7 @@ def get_cell_attribute(self, values=1, drop=set(), keep=set(), allvalues=False): return dl_variable_range - def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cmap='viridis', title='', grid=True, legend_loc='lower left', xlim=None, ylim=None, xyequal=True, s=1.0, figsizepx=None, ext='jpeg', figbgcolor=None, **kwargs): + def plot_scatter(self, focus='cell_type', cat_drop=set(), cat_keep=set(), z_slice=0.0, z_axis=None, alpha=1, cmap='viridis', title='', grid=True, legend_loc='lower left', xlim=None, ylim=None, xyequal=True, s=1.0, figsizepx=None, ext='jpeg', figbgcolor=None, **kwargs): """ input: self: TimeSeries class instance @@ -859,6 +862,16 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma focus: string; default is 'cell_type' column name within cell dataframe. + cat_drop: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be dropped for the dataframe. + Attention: when the cat_keep parameter is given, then + the cat_drop parameter has to be an empty set! + + cat_keep: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be kept in the dataframe. + z_slice: floating point number; default is 0.0 z-axis position to slice a 2D xy-plain out of the 3D mesh. if z_slice position is not an exact mesh center coordinate, @@ -951,6 +964,8 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma df_cell = mcds.get_cell_df() o_output = mcds.plot_scatter( focus = focus, + cat_drop = cat_drop, + cat_keep = cat_keep, z_slice = z_slice, z_axis = z_axis, alpha = alpha, @@ -1141,7 +1156,7 @@ def make_ome_tiff(self, cell_attribute='ID', conc_cutoff={}, focus=None, file=Tr ## TIME SERIES RELATED FUNCTIONS ## - def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanmean, frame='cell', z_slice=None, logy=False, ylim=None, secondary_y=None, subplots=False, sharex=False, sharey=False, linestyle='-', linewidth=None, cmap=None, color=None, grid=True, legend=True, yunit=None, title=None, ax=None, figsizepx=[640, 480], ext=None, figbgcolor=None, **kwargs): + def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanmean, frame='cell', cat_drop=set(), cat_keep=(), z_slice=None, logy=False, ylim=None, secondary_y=None, subplots=False, sharex=False, sharey=False, linestyle='-', linewidth=None, cmap=None, color=None, grid=True, legend=True, yunit=None, title=None, ax=None, figsizepx=[640, 480], ext=None, figbgcolor=None, **kwargs): """ input: self: TimeSeries class instance @@ -1162,6 +1177,16 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme cell: dataframe will be retrieved through the mcds.get_cell_df function. conc: dataframe will be retrieved through the mcds.get_conc_df function. + cat_drop: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be dropped for the dataframe. + Attention: when the cat_keep parameter is given, then + the cat_drop parameter has to be an empty set! + + cat_keep: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be kept in the dataframe. + z_slice: floating point number; default is None z-axis position to slice a 2D xy-plain out of the 3D mesh. if z_slice position numeric but not an exact mesh center coordinate, @@ -1233,14 +1258,16 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme to be able to generate movies from the images. ext: string; default is None - output image format. possible formats are None, jpeg, png, and tiff. - if None then the matplotlib figure is returned by the function - and not written to file. + output format. + possible image formats are jpeg, jpg, png, tif, and tiff. + for retrieving a datafarme file use csv. + any other string or a number returns a pandas dataframe object. + None returnes a matplotlib figure object. figbgcolor: string; default is None which is transparent (png) or white (jpeg, tiff). figure background color. - only relevant if ext not is None. + only relevant if ext specifies an image file. **kwargs: possible additional keyword arguments input, handled by the pandas series plot function. @@ -1261,13 +1288,6 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme https://en.wikipedia.org/wiki/Portable_Network_Graphics https://en.wikipedia.org/wiki/TIFF """ - # handle focus - if focus_cat is None: - focus_cat = 'total' - if focus_num is None: - focus_num = 'count' - aggregate_num = len - # handle z_slice if not (z_slice is None): _, _, ar_p_axis = self.get_mcds_list()[0].get_mesh_mnp_axis() @@ -1279,8 +1299,20 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme # generate series dataframe df_series = None for mcds in self.get_mcds_list(): - # fetch cell timestep dataframe + + # cell agent if frame in {'cell', 'df_cell', 'cell_df', 'get_cell_df'}: + + # handle focus + if focus_cat is None: + focus_cat = 'total' + + if focus_num is None: + focus_num = 'count' + aggregate_num = len + + # fetch timestep dataframe + b_verbose = mcds.verbose mcds.set_verbose_false() if (focus_cat == 'total') and (focus_num == 'count'): df_frame = mcds.get_cell_df(values=1, keep={'time'}) @@ -1295,28 +1327,49 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme else: df_frame = mcds.get_cell_df(values=1, keep={focus_cat,focus_num}) mcds.set_verbose_true() - # fetch conc timestep dataframe + mcds.verbose = b_verbose + + # conc substrate elif frame in {'conc', 'df_conc', 'conc_df', 'get_conc_df'}: + + # handle focus + if focus_cat is None: + focus_cat = 'substrate' + + # fetch time step dataframe + b_verbose = mcds.verbose mcds.set_verbose_false() - if (focus_cat == 'total') and (focus_num == 'count'): - df_frame = mcds.get_conc_df(values=1, keep={'time'}) - df_frame['total'] = 'total' - df_frame['count'] = 1 - elif (focus_cat == 'total'): - df_frame = mcds.get_conc_df(values=1, keep={focus_num}) - df_frame['total'] = 'total' - elif (focus_num == 'count'): - df_frame = mcds.get_conc_df(values=1, keep={focus_cat}) - df_frame['count'] = 1 + if (focus_cat == 'substrate'): # and (focus_num == 'value'): + if focus_num is None: + focus_num = 'value' + df_frame = mcds.get_conc_df(values=1).melt( + id_vars = es_coor_conc.difference({'ID'}), + var_name = 'substrate', + ) + else: - df_frame = mcds.get_conc_df(values=1, keep={focus_cat,focus_num}) + if focus_num is None: + sys.exit(f"Error @ TimeSeries.plot_timeseries : with --frame cons and focus_cat set, you have to set focus_num too. for example, choose a substrate.") + df_frame = mcds.get_conc_df(values=1, keep={focus_num}) # focus_num mcds.set_verbose_true() + mcds.verbose = b_verbose + # error else: sys.exit(f"Error @ TimeSeries.plot_timeseries : unknown frame {frame}. known are cell_df and conc_df.") + + # filter categories + es_category = set(df_frame.loc[:, focus_cat]) + if (len(cat_keep) > 0): + es_category = es_category.intersection(cat_keep) + else: + es_category = es_category.difference(cat_drop) + df_frame = df_frame.loc[df_frame.loc[:, focus_cat].isin(es_category),:] + # handle z_slize if not (z_slice is None): df_frame = df_frame.loc[(df_frame.mesh_center_p == z_slice),:] + # calculate focus_num aggregate per focus_cat r_time = mcds.get_time() df_frame = df_frame.loc[:,[focus_cat, focus_num]] @@ -1329,6 +1382,7 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme df_aggregate.columns = [r_time] else: sys.exit(f'Error @ TimeSeries.plot_timeseries : {aggregate_num} calculation returns unexpected variable type {type(o_aggregate)}.\nthe expected type is a pandas Series or DataFrame.') + # store result if (df_series is None): df_series = df_aggregate @@ -1340,92 +1394,110 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme right_index=True, how='outer' ) + # transpose dataframe df_series = df_series.T + df_series.index.name = 'time_min' - # handle ylabel - if (focus_num == 'count') and (yunit is None): - ylabel = focus_num - elif (focus_num == 'count'): - ylabel = f'focus_num [{yunit}]' - elif (yunit is None): - ylabel = f"{aggregate_num.__name__.replace('nan','')} {focus_num}" + # generate file name + if (focus_num == 'count'): + s_ofile = f'timeseries_{frame}_{focus_cat}_{focus_num}.{ext}'.replace(' ','_') else: - ylabel = f"{aggregate_num.__name__.replace('nan','')} {focus_num} [{yunit}]" - - # generate series line plot - if (ax is None): - # handle figure size - figsizepx[0] = figsizepx[0] - (figsizepx[0] % 2) # enforce even pixel number - figsizepx[1] = figsizepx[1] - (figsizepx[1] % 2) - r_px = 1 / plt.rcParams['figure.dpi'] # translate px to inch - figsize = [None, None] - figsize[0] = figsizepx[0] * r_px - figsize[1] = figsizepx[1] * r_px - if self.verbose: - print(f'inch figure size set to {figsize}.') - fig, ax = plt.subplots(figsize=figsize) - else: - fig = plt.gcf() - if not (cmap is None): - # if cmap - df_series.plot( - kind = 'line', - logy = logy, - ylim = ylim, - secondary_y = secondary_y, - subplots = subplots, - sharex = sharex, - sharey = sharey, - linestyle = linestyle, - linewidth = linewidth, - cmap = cmap, - grid = grid, - legend = legend, - ylabel = ylabel, - xlabel = f"time [{mcds.get_unit_dict()['time']}]", - title = title, - ax = ax, - **kwargs, - ) - else: - # if color - df_series.plot( - kind = 'line', - logy = logy, - ylim = ylim, - secondary_y = secondary_y, - subplots = subplots, - sharex = sharex, - sharey = sharey, - linestyle = linestyle, - linewidth = linewidth, - color = color, - grid = grid, - legend = legend, - ylabel = ylabel, - xlabel = f"time [{mcds.get_unit_dict()['time']}]", - title = title, - ax = ax, - **kwargs, - ) + s_ofile = f"timeseries_{frame}_{focus_cat}_{focus_num}_{aggregate_num.__name__.replace('np.nan','')}.{ext}".replace(' ','_') + s_pathfile = self.path + '/' + s_ofile - # output - if (ext is None): - return fig - else: - if (focus_num == 'count'): - s_ofile = f'timeseries_{frame}_{focus_cat}_{focus_num}.{ext}'.replace(' ','_') - else: - s_ofile = f"timeseries_{frame}_{focus_cat}_{focus_num}_{aggregate_num.__name__.replace('np.nan','')}.{ext}".replace(' ','_') - s_pathfile = self.path + '/' + s_ofile - if figbgcolor is None: - figbgcolor = 'auto' - plt.tight_layout() - fig.savefig(s_pathfile, facecolor=figbgcolor) - plt.close(fig) + # output dataframe object + if not (ext in {'csv', 'jpeg', 'jpg', 'png', 'tiff', 'tif', None}): + return df_series + + # output dataframe file + elif (ext == 'csv'): + df_series.to_csv(s_pathfile) return s_pathfile + # output image file + elif (ext in {'jpeg','jpg','png','tiff','tif', None}): + # handle ylabel + if (focus_num == 'count') and (yunit is None): + ylabel = focus_num + elif (focus_num == 'count'): + ylabel = f'focus_num [{yunit}]' + elif (yunit is None): + ylabel = f"{aggregate_num.__name__.replace('nan','')} {focus_num}" + else: + ylabel = f"{aggregate_num.__name__.replace('nan','')} {focus_num} [{yunit}]" + + # generate series line plot + if (ax is None): + # handle figure size + figsizepx[0] = figsizepx[0] - (figsizepx[0] % 2) # enforce even pixel number + figsizepx[1] = figsizepx[1] - (figsizepx[1] % 2) + r_px = 1 / plt.rcParams['figure.dpi'] # translate px to inch + figsize = [None, None] + figsize[0] = figsizepx[0] * r_px + figsize[1] = figsizepx[1] * r_px + if self.verbose: + print(f'inch figure size set to {figsize}.') + fig, ax = plt.subplots(figsize=figsize) + else: + fig = plt.gcf() + if not (cmap is None): + # if cmap + df_series.plot( + kind = 'line', + logy = logy, + ylim = ylim, + secondary_y = secondary_y, + subplots = subplots, + sharex = sharex, + sharey = sharey, + linestyle = linestyle, + linewidth = linewidth, + cmap = cmap, + grid = grid, + legend = legend, + ylabel = ylabel, + xlabel = f"time [{mcds.get_unit_dict()['time']}]", + title = title, + ax = ax, + **kwargs, + ) + else: + # if color + df_series.plot( + kind = 'line', + logy = logy, + ylim = ylim, + secondary_y = secondary_y, + subplots = subplots, + sharex = sharex, + sharey = sharey, + linestyle = linestyle, + linewidth = linewidth, + color = color, + grid = grid, + legend = legend, + ylabel = ylabel, + xlabel = f"time [{mcds.get_unit_dict()['time']}]", + title = title, + ax = ax, + **kwargs, + ) + + + # save fig to file + if not (ext is None): + if figbgcolor is None: + figbgcolor = 'auto' + plt.tight_layout() + fig.savefig(s_pathfile, facecolor=figbgcolor) + plt.close(fig) + return s_pathfile + + # output matplotlib fig object + else: + return fig + ## GRAPH RELATED FUNCTIONS ## diff --git a/pcdl/timestep.py b/pcdl/timestep.py index c727261..fde35d7 100644 --- a/pcdl/timestep.py +++ b/pcdl/timestep.py @@ -477,7 +477,7 @@ def _anndextract(df_cell, scale='maxabs', graph_attached={}, graph_neighbor={}, # object classes class TimeStep: - def __init__(self, xmlfile, output_path='.', custom_data_type={}, microenv=True, graph=True, physiboss=True, settingxml='PhysiCell_settings.xml', verbose=True): + def __init__(self, xmlfile, output_path='.', custom_data_type={}, microenv=True, graph=True, physiboss=True, settingxml=False, verbose=True): """ input: xmlfile: string @@ -506,7 +506,7 @@ def __init__(self, xmlfile, output_path='.', custom_data_type={}, microenv=True, should physiboss state data be loaded, if found? setting physiboss to False will use less memory and speed up processing. - settingxml: string; default PhysiCell_settings.xml + settingxml: string; default False the settings.xml that is loaded, from which the cell type ID label mapping, is extracted, if this information is not found in the output xml file. @@ -1518,12 +1518,22 @@ def get_cell_attribute_list(self): return self.data['cell']['ls_cellattr'].copy() - def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cmap='viridis', title=None, grid=True, legend_loc='lower left', xlim=None, ylim=None, xyequal=True, s=1.0, ax=None, figsizepx=None, ext=None, figbgcolor=None, **kwargs): + def plot_scatter(self, focus='cell_type', cat_drop=set(), cat_keep=set(), z_slice=0.0, z_axis=None, alpha=1, cmap='viridis', title=None, grid=True, legend_loc='lower left', xlim=None, ylim=None, xyequal=True, s=1.0, ax=None, figsizepx=None, ext=None, figbgcolor=None, **kwargs): """ input: focus: string; default is 'cell_type' column name within cell dataframe. + cat_drop: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be dropped for the dataframe. + Attention: when the cat_keep parameter is given, then + the cat_drop parameter has to be an empty set! + + cat_keep: set of strings; default is an empty set + if focus is a categorical attribute, + set of category labels to be kept in the dataframe. + z_slice: floating point number; default is 0.0 z-axis position to slice a 2D xy-plain out of the 3D substrate concentration mesh. if z_slice position @@ -1721,6 +1731,13 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma s_cmap = cmap, b_shuffle = False, ) + # filter categories + es_cat = set() + if (len(cat_keep) > 0): + es_cat = es_category.intersection(cat_keep) + else: + es_cat = es_category.difference(cat_drop) + df_cell= df_cell.loc[df_cell.loc[:,focus].isin(es_cat),:] # generate color list c = list(df_cell.loc[:, s_focus_color].values) s_cmap = None @@ -2699,7 +2716,7 @@ def _read_xml(self, xmlfile, output_path='.'): break # update cell_type ID label dictionar - # metadata cell_type label:id mapping detection ~ physicell version >= 3.15 (gold quality) + # metadata cell_type label:id mapping detection ~ physicell version >= 1.13 (gold quality) try: for x_celltype in x_celldata.find('cell_types').findall('type'): s_id = str(x_celltype.get('ID')) diff --git a/test/test_commandline_2d.py b/test/test_commandline_2d.py index c0a26b1..e4ca9e2 100644 --- a/test/test_commandline_2d.py +++ b/test/test_commandline_2d.py @@ -1217,6 +1217,8 @@ def test_pcdl_plot_scatter_set(self): '--microenv', 'True', '--physiboss', 'false', '--settingxml', 'false', + '--cat_drop', '', + '--cat_keep', '', '--z_slice', '1.1', '--z_axis', '0.0', '40.0', '--alpha', '0.5', @@ -1403,6 +1405,8 @@ class TestCommandLineInterfacePlotTimeSeries(object): # + focus_cat ('none', _cell_type_) ok # + focus_num ('none', _oxygen_) ok # + aggregate_num ('mean', 'entropy') ok + # + cat_drop ('', '1 2 3 4') + # + cat_keep ('', '1 2 3 4') # + frame ('cell', 'conc') # + z_slice ('none', _1.1_) ok # + logy (false, _true_) @@ -1412,7 +1416,7 @@ class TestCommandLineInterfacePlotTimeSeries(object): # + sharex (false, _true_) # + sharey (false, _true_) # + linestyle ('-', '-.') - # + linewidth ('none', 9) + # + linewidth ('none', 9.0) # + cmap ('none', 'magma') # + color ('none', 'maroon') # + grid (true, _false_) @@ -1420,7 +1424,7 @@ class TestCommandLineInterfacePlotTimeSeries(object): # + yunit ('none', 'myunit') # + title ('none', 'my title') # + figsizepx (none, _[641, 481]_) - # + ext (jpeg, _tiff_) + # + ext (csv, jpeg, png, _tiff_) # + figbgcolor (none, _yellow_) def test_pcdl_plot_timeseries_default(self): @@ -1436,12 +1440,14 @@ def test_pcdl_plot_timeseries_default(self): def test_pcdl_plot_timeseries_set(self): o_result = subprocess.run([ - 'pcdl_plot_timeseries', s_path_2d, 'None', 'oxygen', 'entropy', '-v', 'false', + 'pcdl_plot_timeseries', s_path_2d, 'None', 'None', 'entropy', '-v', 'false', '--custom_data_type', 'sample:bool', - '--microenv', 'True', + '--microenv', 'true', '--physiboss', 'false', '--settingxml', 'false', '--frame', 'conc', + '--cat_drop', + '--cat_keep', '--z_slice', '1.1', '--logy', 'true', '--ylim', '6.0', '7.0', @@ -1450,7 +1456,7 @@ def test_pcdl_plot_timeseries_set(self): '--sharex', 'true', '--sharey', 'true', '--linestyle', ':', - '--linewidth', '9', + '--linewidth', '9.0', '--cmap', 'magma', '--color', 'maroon', 'orange', 'yellow', '--grid', 'false', @@ -1465,7 +1471,7 @@ def test_pcdl_plot_timeseries_set(self): print(f'o_result.returncode: {o_result.returncode}\n') print(f'o_result.stdout: {o_result.stdout}\n') print(f'o_result.stderr: {o_result.stderr}\n') - os.remove(f'{s_path_2d}/timeseries_conc_total_oxygen_entropy.tiff') + os.remove(f'{s_path_2d}/timeseries_conc_substrate_value_entropy.tiff') assert o_result.returncode == 0 diff --git a/test/test_timeseries_2d.py b/test/test_timeseries_2d.py index 7120c81..1477da8 100644 --- a/test/test_timeseries_2d.py +++ b/test/test_timeseries_2d.py @@ -363,7 +363,9 @@ def test_mcdsts_get_cell_attribute_allvalues(self, mcdsts=mcdsts): def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): ls_pathfile = mcdsts.plot_scatter( focus='pressure', # case numeric - z_slice = -3.333, # test if + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} + z_slice = -3.333, # test if z_axis = None, # test iff numeric #alpha = 1, # matplotlib #cmap = 'viridis', # matplotlib @@ -392,7 +394,9 @@ def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): def test_mcdsts_plot_scatter_cat(self, mcdsts=mcdsts): l_fig = mcdsts.plot_scatter( focus='cell_type', # case categorical - z_slice = 0.0, # jump over if + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} + z_slice = 0.0, # jump over if z_axis = None, # test iff categorical #alpha = 1, # TimeStep #cmap = 'viridis', # TimeStep @@ -569,6 +573,8 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) focus_num = None, # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = None, # test timeseries #logy = False, # pandas #ylim = None, # pandas @@ -586,7 +592,7 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) #title = None, pandas ax = ax, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = 'jpeg', # test if else {'jpeg', None} + ext = 'jpeg', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ @@ -594,12 +600,14 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) (os.path.exists(s_pathfile)) os.remove(s_pathfile) - def test_mcdsts_plot_timeseries_cat_none_yunit_cell(self, mcdsts=mcdsts): - fig = mcdsts.plot_timeseries( + def test_mcdsts_plot_timeseries_cat_none_catdrop_cell_csv(self, mcdsts=mcdsts): + s_pathfile = mcdsts.plot_timeseries( focus_cat = 'cell_type', # test if {None/total, 'cell_type'} focus_num = None, # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'df_cell', # test if else {'df_cell', 'df_conc'} + cat_drop = {'default'}, # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -613,23 +621,58 @@ def test_mcdsts_plot_timeseries_cat_none_yunit_cell(self, mcdsts=mcdsts): #color = None, # pandas #grid = True, # pandas #legend = True, - yunit = 'mmHg', # test if {None, 'mmHg'} + yunit = None, # test if {None, 'mmHg'} #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = 'csv', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (str(type(fig)) == "") + (s_pathfile.endswith('/pcdl/output_2d/timeseries_df_cell_cell_type_count.csv')) and \ + (os.path.exists(s_pathfile)) + os.remove(s_pathfile) + + def test_mcdsts_plot_timeseries_cat_none_catkeep_cell_df(self, mcdsts=mcdsts): + df = mcdsts.plot_timeseries( + focus_cat = 'cell_type', # test if {None/total, 'cell_type'} + focus_num = None, # test if {None/count, 'oxygen'} + #aggregate_num = np.mean, # pandas + frame = 'df_cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = {'default'}, # test if else {set(), {'default'}} + z_slice = -0.3, # test if if + #logy = False, # pandas + #ylim = None, # pandas + #secondary_y = None, # pandas + #subplots = False, # pandas + #sharex = False, # pandas + #sharey = False, # pandas + #linestyle = '-', # pandas + #linewidth = None, # pandas + #cmap = None, # pandas + #color = None, # pandas + #grid = True, # pandas + #legend = True, + yunit = None, # test if {None, 'mmHg'} + #title = None, pandas + ax = None, # test if else {None, ax} + figsizepx = [641, 481], # test non even pixel number + ext = 0, # test if else {'jpeg', 'csv', 0, None} + figbgcolor = None # test if + ) + assert(str(type(mcdsts)) == "") and \ + (str(type(df)) == "") plt.close() - def test_mcdsts_plot_timeseries_none_num_yunit_cell(self, mcdsts=mcdsts): + def test_mcdsts_plot_timeseries_none_num_yunit_cell_fig(self, mcdsts=mcdsts): fig = mcdsts.plot_timeseries( focus_cat = None, # test if {None/total, 'cell_type'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'df_cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -647,19 +690,21 @@ def test_mcdsts_plot_timeseries_none_num_yunit_cell(self, mcdsts=mcdsts): #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ (str(type(fig)) == "") plt.close() - def test_mcdsts_plot_timeseries_cat_num_none_cell(self, mcdsts=mcdsts): + def test_mcdsts_plot_timeseries_cat_num_none_cell_fig(self, mcdsts=mcdsts): fig = mcdsts.plot_timeseries( focus_cat = 'cell_type', # test if {None/total, 'cell_type'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -677,7 +722,7 @@ def test_mcdsts_plot_timeseries_cat_num_none_cell(self, mcdsts=mcdsts): #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ @@ -691,6 +736,8 @@ def test_mcdsts_plot_timeseries_none_none_none_conc_ax_jpeg(self, mcdsts=mcdsts) focus_num = None, # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} z_slice = None, # test timeseries #logy = False, # pandas #ylim = None, # pandas @@ -708,21 +755,23 @@ def test_mcdsts_plot_timeseries_none_none_none_conc_ax_jpeg(self, mcdsts=mcdsts) #title = None, pandas ax = ax, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = 'jpeg', # test if else {'jpeg', None} + ext = 'jpeg', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/output_2d/timeseries_conc_total_count.jpeg')) and \ + (s_pathfile.endswith('/pcdl/output_2d/timeseries_conc_substrate_value_nanmean.jpeg')) and \ (os.path.exists(s_pathfile)) os.remove(s_pathfile) plt.close() - def test_mcdsts_plot_timeseries_cat_none_yunit_conc(self, mcdsts=mcdsts): + def test_mcdsts_plot_timeseries_cat_num_none_conc_fig(self, mcdsts=mcdsts): fig = mcdsts.plot_timeseries( focus_cat = 'voxel_i', # test if {None/total, 'voxel_i'} - focus_num = None, # test if {None/count, 'oxygen'} + focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas - frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + frame = 'conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -736,23 +785,25 @@ def test_mcdsts_plot_timeseries_cat_none_yunit_conc(self, mcdsts=mcdsts): #color = None, # pandas #grid = True, # pandas #legend = True, - yunit = 'mmHg', # test if {None, 'mmHg'} + yunit = None, # test if {None, 'mmHg'} #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ (str(type(fig)) == "") plt.close() - def test_mcdsts_plot_timeseries_none_num_yunit_conc(self, mcdsts=mcdsts): - fig = mcdsts.plot_timeseries( - focus_cat = None, # test if {None/total, 'voxel_i'} + def test_mcdsts_plot_timeseries_cat_num_catdrop_conc_csv(self, mcdsts=mcdsts): + s_pathfile = mcdsts.plot_timeseries( + focus_cat = 'voxel_i', # test if {None/total, 'voxel_i'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + cat_drop = {1,2,3,4}, # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -766,23 +817,26 @@ def test_mcdsts_plot_timeseries_none_num_yunit_conc(self, mcdsts=mcdsts): #color = None, # pandas #grid = True, # pandas #legend = True, - yunit = 'mmHg', # test if {None, 'mmHg'} + yunit = None, # test if {None, 'mmHg'} #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = 'csv', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (str(type(fig)) == "") - plt.close() + (s_pathfile.endswith('/pcdl/output_2d/timeseries_df_conc_voxel_i_oxygen_nanmean.csv')) and \ + (os.path.exists(s_pathfile)) + os.remove(s_pathfile) - def test_mcdsts_plot_timeseries_cat_num_none_conc(self, mcdsts=mcdsts): - fig = mcdsts.plot_timeseries( + def test_mcdsts_plot_timeseries_cat_num_catkeep_conc_df(self, mcdsts=mcdsts): + df = mcdsts.plot_timeseries( focus_cat = 'voxel_i', # test if {None/total, 'voxel_i'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas - frame = 'conc', # test if else {'df_cell', 'df_conc'} + frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = {1,2,3,4}, # test if else {set(), {1,2,3,4}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -800,7 +854,39 @@ def test_mcdsts_plot_timeseries_cat_num_none_conc(self, mcdsts=mcdsts): #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = 0, # test if else {'jpeg', 'csv', 0, None} + figbgcolor = None # test if + ) + assert(str(type(mcdsts)) == "") and \ + (str(type(df)) == "") + plt.close() + + def test_mcdsts_plot_timeseries_none_none_yunit_conc_fig(self, mcdsts=mcdsts): + fig = mcdsts.plot_timeseries( + focus_cat = None, # test if {None/total, 'voxel_i'} + focus_num = None, # test if {None/count, 'oxygen'} + #aggregate_num = np.mean, # pandas + frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} + z_slice = -0.3, # test if if + #logy = False, # pandas + #ylim = None, # pandas + #secondary_y = None, # pandas + #subplots = False, # pandas + #sharex = False, # pandas + #sharey = False, # pandas + #linestyle = '-', # pandas + #linewidth = None, # pandas + #cmap = None, # pandas + #color = None, # pandas + #grid = True, # pandas + #legend = True, + yunit = 'mmHg', # test if {None, 'mmHg'} + #title = None, pandas + ax = None, # test if else {None, ax} + figsizepx = [641, 481], # test non even pixel number + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ diff --git a/test/test_timeseries_3d.py b/test/test_timeseries_3d.py index bbf9a8e..83ed8e2 100644 --- a/test/test_timeseries_3d.py +++ b/test/test_timeseries_3d.py @@ -290,7 +290,9 @@ def test_mcdsts_get_cell_attribute_allvalues(self, mcdsts=mcdsts): def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): ls_pathfile = mcdsts.plot_scatter( focus='pressure', # case numeric - z_slice = -3.333, # test if + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} + z_slice = -3.333, # test if z_axis = None, # test iff numeric #alpha = 1, # matplotlib #cmap = 'viridis', # matplotlib @@ -319,7 +321,9 @@ def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): def test_mcdsts_plot_scatter_cat(self, mcdsts=mcdsts): l_fig = mcdsts.plot_scatter( focus='cell_type', # case categorical - z_slice = 0.0, # jump over if + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} + z_slice = 0.0, # jump over if z_axis = None, # test iff categorical #alpha = 1, # TimeStep #cmap = 'viridis', # TimeStep @@ -433,6 +437,8 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) focus_num = None, # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = None, # test timeseries #logy = False, # pandas #ylim = None, # pandas @@ -450,7 +456,7 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) #title = None, pandas ax = ax, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = 'jpeg', # test if else {'jpeg', None} + ext = 'jpeg', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ @@ -458,12 +464,14 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) (os.path.exists(s_pathfile)) os.remove(s_pathfile) - def test_mcdsts_plot_timeseries_cat_none_yunit_cell(self, mcdsts=mcdsts): - fig = mcdsts.plot_timeseries( + def test_mcdsts_plot_timeseries_cat_none_catdrop_cell_csv(self, mcdsts=mcdsts): + s_pathfile = mcdsts.plot_timeseries( focus_cat = 'cell_type', # test if {None/total, 'cell_type'} focus_num = None, # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'df_cell', # test if else {'df_cell', 'df_conc'} + cat_drop = {'default'}, # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -477,23 +485,58 @@ def test_mcdsts_plot_timeseries_cat_none_yunit_cell(self, mcdsts=mcdsts): #color = None, # pandas #grid = True, # pandas #legend = True, - yunit = 'mmHg', # test if {None, 'mmHg'} + yunit = None, # test if {None, 'mmHg'} #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = 'csv', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (str(type(fig)) == "") + (s_pathfile.endswith('/pcdl/output_3d/timeseries_df_cell_cell_type_count.csv')) and \ + (os.path.exists(s_pathfile)) + os.remove(s_pathfile) + + def test_mcdsts_plot_timeseries_cat_none_catkeep_cell_df(self, mcdsts=mcdsts): + df = mcdsts.plot_timeseries( + focus_cat = 'cell_type', # test if {None/total, 'cell_type'} + focus_num = None, # test if {None/count, 'oxygen'} + #aggregate_num = np.mean, # pandas + frame = 'df_cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = {'default'}, # test if else {set(), {'default'}} + z_slice = -0.3, # test if if + #logy = False, # pandas + #ylim = None, # pandas + #secondary_y = None, # pandas + #subplots = False, # pandas + #sharex = False, # pandas + #sharey = False, # pandas + #linestyle = '-', # pandas + #linewidth = None, # pandas + #cmap = None, # pandas + #color = None, # pandas + #grid = True, # pandas + #legend = True, + yunit = None, # test if {None, 'mmHg'} + #title = None, pandas + ax = None, # test if else {None, ax} + figsizepx = [641, 481], # test non even pixel number + ext = 0, # test if else {'jpeg', 'csv', 0, None} + figbgcolor = None # test if + ) + assert(str(type(mcdsts)) == "") and \ + (str(type(df)) == "") plt.close() - def test_mcdsts_plot_timeseries_none_num_yunit_cell(self, mcdsts=mcdsts): + def test_mcdsts_plot_timeseries_none_num_yunit_cell_fig(self, mcdsts=mcdsts): fig = mcdsts.plot_timeseries( focus_cat = None, # test if {None/total, 'cell_type'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'df_cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -511,19 +554,21 @@ def test_mcdsts_plot_timeseries_none_num_yunit_cell(self, mcdsts=mcdsts): #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ (str(type(fig)) == "") plt.close() - def test_mcdsts_plot_timeseries_cat_num_none_cell(self, mcdsts=mcdsts): + def test_mcdsts_plot_timeseries_cat_num_none_cell_fig(self, mcdsts=mcdsts): fig = mcdsts.plot_timeseries( focus_cat = 'cell_type', # test if {None/total, 'cell_type'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'cell', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {'default'}} + cat_keep = set(), # test if else {set(), {'default'}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -541,7 +586,7 @@ def test_mcdsts_plot_timeseries_cat_num_none_cell(self, mcdsts=mcdsts): #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ @@ -555,6 +600,8 @@ def test_mcdsts_plot_timeseries_none_none_none_conc_ax_jpeg(self, mcdsts=mcdsts) focus_num = None, # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} z_slice = None, # test timeseries #logy = False, # pandas #ylim = None, # pandas @@ -572,21 +619,23 @@ def test_mcdsts_plot_timeseries_none_none_none_conc_ax_jpeg(self, mcdsts=mcdsts) #title = None, pandas ax = ax, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = 'jpeg', # test if else {'jpeg', None} + ext = 'jpeg', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/output_3d/timeseries_conc_total_count.jpeg')) and \ + (s_pathfile.endswith('/pcdl/output_3d/timeseries_conc_substrate_value_nanmean.jpeg')) and \ (os.path.exists(s_pathfile)) os.remove(s_pathfile) plt.close() - def test_mcdsts_plot_timeseries_cat_none_yunit_conc(self, mcdsts=mcdsts): + def test_mcdsts_plot_timeseries_cat_num_none_conc_fig(self, mcdsts=mcdsts): fig = mcdsts.plot_timeseries( focus_cat = 'voxel_i', # test if {None/total, 'voxel_i'} - focus_num = None, # test if {None/count, 'oxygen'} + focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas - frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + frame = 'conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -600,23 +649,25 @@ def test_mcdsts_plot_timeseries_cat_none_yunit_conc(self, mcdsts=mcdsts): #color = None, # pandas #grid = True, # pandas #legend = True, - yunit = 'mmHg', # test if {None, 'mmHg'} + yunit = None, # test if {None, 'mmHg'} #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ (str(type(fig)) == "") plt.close() - def test_mcdsts_plot_timeseries_none_num_yunit_conc(self, mcdsts=mcdsts): - fig = mcdsts.plot_timeseries( - focus_cat = None, # test if {None/total, 'voxel_i'} + def test_mcdsts_plot_timeseries_cat_num_catdrop_conc_csv(self, mcdsts=mcdsts): + s_pathfile = mcdsts.plot_timeseries( + focus_cat = 'voxel_i', # test if {None/total, 'voxel_i'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + cat_drop = {1,2,3,4}, # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -630,23 +681,26 @@ def test_mcdsts_plot_timeseries_none_num_yunit_conc(self, mcdsts=mcdsts): #color = None, # pandas #grid = True, # pandas #legend = True, - yunit = 'mmHg', # test if {None, 'mmHg'} + yunit = None, # test if {None, 'mmHg'} #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = 'csv', # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (str(type(fig)) == "") - plt.close() + (s_pathfile.endswith('/pcdl/output_3d/timeseries_df_conc_voxel_i_oxygen_nanmean.csv')) and \ + (os.path.exists(s_pathfile)) + os.remove(s_pathfile) - def test_mcdsts_plot_timeseries_cat_num_none_conc(self, mcdsts=mcdsts): - fig = mcdsts.plot_timeseries( + def test_mcdsts_plot_timeseries_cat_num_catkeep_conc_df(self, mcdsts=mcdsts): + df = mcdsts.plot_timeseries( focus_cat = 'voxel_i', # test if {None/total, 'voxel_i'} focus_num = 'oxygen', # test if {None/count, 'oxygen'} #aggregate_num = np.mean, # pandas - frame = 'conc', # test if else {'df_cell', 'df_conc'} + frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = {1,2,3,4}, # test if else {set(), {1,2,3,4}} z_slice = -0.3, # test if if #logy = False, # pandas #ylim = None, # pandas @@ -664,7 +718,39 @@ def test_mcdsts_plot_timeseries_cat_num_none_conc(self, mcdsts=mcdsts): #title = None, pandas ax = None, # test if else {None, ax} figsizepx = [641, 481], # test non even pixel number - ext = None, # test if else {'jpeg', None} + ext = 0, # test if else {'jpeg', 'csv', 0, None} + figbgcolor = None # test if + ) + assert(str(type(mcdsts)) == "") and \ + (str(type(df)) == "") + plt.close() + + def test_mcdsts_plot_timeseries_none_none_yunit_conc_fig(self, mcdsts=mcdsts): + fig = mcdsts.plot_timeseries( + focus_cat = None, # test if {None/total, 'voxel_i'} + focus_num = None, # test if {None/count, 'oxygen'} + #aggregate_num = np.mean, # pandas + frame = 'df_conc', # test if else {'df_cell', 'df_conc'} + cat_drop = set(), # test if else {set(), {1,2,3,4}} + cat_keep = set(), # test if else {set(), {1,2,3,4}} + z_slice = -0.3, # test if if + #logy = False, # pandas + #ylim = None, # pandas + #secondary_y = None, # pandas + #subplots = False, # pandas + #sharex = False, # pandas + #sharey = False, # pandas + #linestyle = '-', # pandas + #linewidth = None, # pandas + #cmap = None, # pandas + #color = None, # pandas + #grid = True, # pandas + #legend = True, + yunit = 'mmHg', # test if {None, 'mmHg'} + #title = None, pandas + ax = None, # test if else {None, ax} + figsizepx = [641, 481], # test non even pixel number + ext = None, # test if else {'jpeg', 'csv', 0, None} figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ diff --git a/test/test_timestep_2d.py b/test/test_timestep_2d.py index f09ca37..7d76341 100644 --- a/test/test_timestep_2d.py +++ b/test/test_timestep_2d.py @@ -630,7 +630,9 @@ def test_mcds_get_cell_df_keep(self, mcds=mcds): def test_mcds_plot_scatter_cat_if(self, mcds=mcds): fig = mcds.plot_scatter( focus='cell_type', # case categorical - z_slice = -3.333, # test if + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} + z_slice = -3.333, # test if z_axis = None, # test if case categorical #alpha = 1, # matplotlib cmap = 'viridis', # else case es_categorical @@ -653,10 +655,12 @@ def test_mcds_plot_scatter_cat_if(self, mcds=mcds): def test_mcds_plot_scatter_cat_else1(self, mcds=mcds): s_pathfile = mcds.plot_scatter( focus='cell_type', # case categorical + cat_drop = {'blood_cells'}, # set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = 0, # jump over if - z_axis = {'cancer_cell'}, # test else case categorical + z_axis = {'default'}, # test else case categorical #alpha = 1, # matplotlib - cmap = {'cancer_cell': 'maroon'}, # test if case es_categorical + cmap = {'default': 'maroon'}, # test if case es_categorical title ='test_mcds_plot_scatter_else', # matplotlib #grid = True, # matplotlib #legend_loc = 'lower left', # matplotlib @@ -679,8 +683,10 @@ def test_mcds_plot_scatter_cat_else2(self, mcds=mcds): fig, ax = plt.subplots() mcds.plot_scatter( focus='cell_type', # case categorical + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = {'default'}, # {set(), {'default'}} z_slice = 0, # jump over if - z_axis = {'cancer_cell'}, # test else case categorical + z_axis = {'default'}, # test else case categorical #alpha = 1, # matplotlib cmap = 'viridis', # test else case es_categorical title ='test_mcds_plot_scatter_else2', # matplotlib @@ -703,6 +709,8 @@ def test_mcds_plot_scatter_cat_else2(self, mcds=mcds): def test_mcds_plot_scatter_num_if(self, mcds=mcds): fig = mcds.plot_scatter( focus='oxygen', # case numeric + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = -3.333, # test if z_axis = None, # test if numeric #alpha = 1, # matplotlib @@ -726,6 +734,8 @@ def test_mcds_plot_scatter_num_if(self, mcds=mcds): def test_mcds_plot_scatter_num_else(self, mcds=mcds): fig = mcds.plot_scatter( focus='oxygen', # case numeric + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = 0, # jump over if z_axis = [0, 38], # test else numeric #alpha = 1, # matplotlib diff --git a/test/test_timestep_3d.py b/test/test_timestep_3d.py index 8b370dd..2e66863 100644 --- a/test/test_timestep_3d.py +++ b/test/test_timestep_3d.py @@ -368,6 +368,8 @@ def test_mcds_plot_scatter_cat_if(self, mcds=mcds): fig, ax = plt.subplots() fig = mcds.plot_scatter( focus='cell_type', # case categorical + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = -3.333, # test if z_axis = None, # test if case categorical #alpha = 1, # matplotlib @@ -391,10 +393,12 @@ def test_mcds_plot_scatter_cat_if(self, mcds=mcds): def test_mcds_plot_scatter_cat_else1(self, mcds=mcds): s_pathfile = mcds.plot_scatter( focus='cell_type', # case categorical + cat_drop = {'blood_cells'}, # set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = 0, # jump over if - z_axis = {'cancer_cell'}, # test else case categorical + z_axis = {'default'}, # test else case categorical #alpha = 1, # matplotlib - cmap = {'cancer_cell': 'maroon'}, # test if case es_categorical + cmap = {'default': 'maroon'}, # test if case es_categorical title ='test_mcds_plot_scatter_else', # matplotlib #grid = True, # matplotlib #legend_loc = 'lower left', # matplotlib @@ -417,8 +421,10 @@ def test_mcds_plot_scatter_cat_else2(self, mcds=mcds): fig, ax = plt.subplots() mcds.plot_scatter( focus='cell_type', # case categorical + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = {'default'}, # {set(), {'default'}} z_slice = 0, # jump over if - z_axis = {'cancer_cell'}, # test else case categorical + z_axis = {'default'}, # test else case categorical #alpha = 1, # matplotlib cmap = 'viridis', # test else case es_categorical title ='test_mcds_plot_scatter_else2', # matplotlib @@ -441,6 +447,8 @@ def test_mcds_plot_scatter_cat_else2(self, mcds=mcds): def test_mcds_plot_scatter_num_if(self, mcds=mcds): fig = mcds.plot_scatter( focus='oxygen', # case numeric + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = -3.333, # test if z_axis = None, # test if numeric #alpha = 1, # matplotlib @@ -464,6 +472,8 @@ def test_mcds_plot_scatter_num_if(self, mcds=mcds): def test_mcds_plot_scatter_num_else(self, mcds=mcds): fig = mcds.plot_scatter( focus='oxygen', # case numeric + cat_drop = set(), # {set(), {'blood_cells'}} + cat_keep = set(), # {set(), {'default'}} z_slice = 0, # jump over if z_axis = [0, 38], # test else numeric #alpha = 1, # matplotlib