Skip to content
Snippets Groups Projects
Commit a608cfaf authored by Hock, Martin's avatar Hock, Martin
Browse files

Merge branch '65-default-name-for-exported-plots' into 'dev'

Resolve "Default name for exported plots"

See merge request !48
parents d5b1fdff c643cb71
No related branches found
No related tags found
2 merge requests!52Create v0.2.2,!48Resolve "Default name for exported plots"
Pipeline #855259 waiting for manual action
......@@ -59,9 +59,9 @@ Optional parameters can be used to customize the tag process.
- *prefix* : str, optional
Will be added as prefix to the ID.
- *id_method* : str, optional
id_method for creating the ID. Create an ID by Unix time is referenced as 'time', create a random ID with id_method='random'. The default is 'time'.
id_method for creating the ID. Create an ID by Unix time is referenced as "time", create a random ID with id_method="random". The default is "time".
- *location* : string, optional
Location for ID to be displayed on the plot. Default is 'east'.
Location for ID to be displayed on the plot. Default is "east".
- *qrcode* : boolean, optional
Experimental support for encoding the ID in a QR Code.
- *id_on_plot* : boolean, optional
......@@ -72,13 +72,13 @@ Example:
FIG1 = plt.figure()
FIG2 = plt.figure()
FIGS_AS_LIST = [FIG1, FIG2]
FIGS_AND_IDS = tagplot(FIGS_AS_LIST, 'matplotlib', prefix='XY23_', id_method='random', location='west')
FIGS_AND_IDS = tagplot(FIGS_AS_LIST, "matplotlib", prefix="XY23_", id_method="random", location="west")
```
### publish()
Save plot, data and measuring script. It is possible to export multiple figures at once.
`publish(figs_and_ids, src_datapath, dst_path, plot_name)`
`publish(figs_and_ids, src_datapath, dst_path)`
- *figs_and_ids* must be a PlotIDTransfer object. Therefore, it can be directly passed from tagplot() to publish().
- *src_datapath* specifies the path to (raw) data that should be published. It can be a string or a list of strings that specifies all files and directories which will be published.
......@@ -90,8 +90,10 @@ Optional parameters can be used to customize the publish process.
Method how the data should be stored. Available options:
- *centralized*: The raw data will copied only once. All other plots will reference this data via sym link.
- *individual*: The complete raw data will be copied to a folder for every plot, respectively.
- *plot_names* : str or list of str, optional
Name for the exported plot. If not provided, the corresponding IDs will be used.
Example:
`publish(figs_and_ids, '/home/user/Documents/research_data', '/home/user/Documents/exported_data', 'EnergyOverTime-Plot')`
`publish(figs_and_ids, "/home/user/Documents/research_data", "/home/user/Documents/exported_data", plot_names=["EnergyOverTime-Plot", "TimeOverEnergy-Plot")`
## Build
If you want to build plotID yourself, follow these steps:
......
......@@ -35,6 +35,6 @@ FIGS_AND_IDS = tagplot(
# Export your tagged images, copy the research data that generated the images,
# specify the destination folder and give a name for the exported image files.
publish(FIGS_AND_IDS, ["../README.md", "../docs", "../LICENSE"], "./data", "my_image")
publish(FIGS_AND_IDS, ["../README.md", "../docs", "../LICENSE"], "./data")
# Required arguments: publish(output of tagplot(), list of files,
# path to destination folder, name(s) for the resulting images)
# path to destination folder)
......@@ -46,6 +46,6 @@ FIGS_AND_IDS = tagplot(
# %% Publish
publish(FIGS_AND_IDS, ["../README.md", "../docs", "../LICENSE"], "data", "my_plot")
publish(FIGS_AND_IDS, ["../README.md", "../docs", "../LICENSE"], "data")
# Required arguments: publish(output of tagplot(), list of files,
# path to destination folder, name(s) for the resulting images)
# path to destination folder)
......@@ -33,17 +33,17 @@ class PublishOptions:
Export the plot and copy specified files to the destiantion folder.
"""
def __init__(self, figs_and_ids, src_datapaths, dst_path, plot_names, **kwargs):
def __init__(self, figs_and_ids, src_datapaths, dst_path, **kwargs):
if not isinstance(figs_and_ids, PlotIDTransfer):
raise RuntimeError("figs_and_ids is not an instance of " "PlotIDTransfer.")
raise RuntimeError("figs_and_ids is not an instance of PlotIDTransfer.")
self.figure = figs_and_ids.figs
self.figure_ids = figs_and_ids.figure_ids
self.src_datapaths = src_datapaths
self.dst_path = os.path.abspath(dst_path)
self.plot_names = plot_names
self.data_storage = kwargs.get("data_storage", "individual")
self.dst_path_head, self.dst_dirname = os.path.split(self.dst_path)
self.plot_names = kwargs.get("plot_names", self.figure_ids)
def __str__(self):
"""Representation if an object of this class is printed."""
......@@ -91,7 +91,7 @@ class PublishOptions:
# Check if data_storage is a string
if not isinstance(self.data_storage, str):
raise TypeError("The specified data_storage method is not a " "string.")
raise TypeError("The specified data_storage method is not a string.")
def export(self):
"""
......@@ -160,7 +160,7 @@ class PublishOptions:
if delete_dir in ("yes", "y", "Yes", "YES"):
shutil.rmtree(dst_path_invisible)
raise RuntimeError(
"Publishing was unsuccessful. " "Try re-running publish."
"Publishing was unsuccessful. Try re-running publish."
) from exc
case _:
raise ValueError(
......@@ -233,7 +233,7 @@ class PublishOptions:
)
def publish(figs_and_ids, src_datapath, dst_path, plot_name, **kwargs):
def publish(figs_and_ids, src_datapath, dst_path, **kwargs):
"""
Save plot, data and measuring script.
......@@ -245,8 +245,7 @@ def publish(figs_and_ids, src_datapath, dst_path, plot_name, **kwargs):
Path to data that should be published.
dst_path : str
Path to the destination directory.
plot_name : str or list of str
Name for the exported plot.
**kwargs : dict, optional
Extra arguments for additional publish options.
......@@ -258,14 +257,14 @@ def publish(figs_and_ids, src_datapath, dst_path, plot_name, **kwargs):
will reference this data via sym link.
individual [default]: The complete raw data will be copied to a
folder for every plot, respectively.
plot_names : str or list of str, optional
Name for the exported plot. If not provided, the corresponding IDs will be used.
Returns
-------
None.
"""
publish_container = PublishOptions(
figs_and_ids, src_datapath, dst_path, plot_name, **kwargs
)
publish_container = PublishOptions(figs_and_ids, src_datapath, dst_path, **kwargs)
publish_container.validate_input()
publish_container.export()
......@@ -58,7 +58,7 @@ class TestPublish(unittest.TestCase):
PlotIDTransfer(FIG, "testID"),
SRC_DIR,
DST_PATH + "/",
PIC_NAME,
plot_names=PIC_NAME,
data_storage="individual",
)
assert os.path.isfile(os.path.join(DST_PATH, "testID", PIC_NAME + ".png"))
......@@ -70,29 +70,47 @@ class TestPublish(unittest.TestCase):
"from a Python script. Therefore, the script cannot be "
"copied.",
)
def test_publish_multiple_figs(self):
def test_publish_multiple_figs_custom_name(self):
"""
Test publish with multiple figures and check if all exported picture
files exist.
files exist with the provided strings as their names.
"""
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME_LIST)
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, plot_names=PIC_NAME_LIST)
for i, name in enumerate(PIC_NAME_LIST):
assert os.path.isfile(os.path.join(DST_PATH, IDS_AS_LIST[i], name + ".png"))
# Skip test if tests are run from command line.
@unittest.skipIf(
not os.path.isfile(sys.argv[0]),
"Publish is not called "
"from a Python script. Therefore, the script cannot be "
"copied.",
)
def test_publish_multiple_figs_standard_name(self):
"""
Test publish with multiple figures and check if all exported picture
files exist with the IDs as their names.
"""
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH)
for identifier in IDS_AS_LIST:
assert os.path.isfile(
os.path.join(DST_PATH, identifier, identifier + ".png")
)
def test_figs_and_ids(self):
"""
Test if RuntimeError is raised when figs_and_ids is not an
PlotIDTransfer object.
"""
with self.assertRaises(RuntimeError):
publish("FIGS_AND_IDS", SRC_DIR, DST_PATH, PIC_NAME_LIST)
publish("FIGS_AND_IDS", SRC_DIR, DST_PATH)
def test_wrong_ids(self):
"""Test if Error is raised if IDs are of wrong type."""
with self.assertRaises(TypeError):
publish(PlotIDTransfer(FIG, 3), SRC_DIR, DST_PATH, PIC_NAME)
publish(PlotIDTransfer(FIG, 3), SRC_DIR, DST_PATH)
with self.assertRaises(TypeError):
publish(PlotIDTransfer(FIG, ["i", 4]), SRC_DIR, DST_PATH, PIC_NAME)
publish(PlotIDTransfer(FIG, ["i", 4]), SRC_DIR, DST_PATH)
def test_publish_multiple_src_files(self):
"""
......@@ -105,7 +123,7 @@ class TestPublish(unittest.TestCase):
FIGS_AND_IDS,
files_and_dir,
DST_PATH,
PIC_NAME_LIST,
plot_names=PIC_NAME_LIST,
data_storage="individual",
)
for identifier in IDS_AS_LIST:
......@@ -117,14 +135,14 @@ class TestPublish(unittest.TestCase):
def test_src_directory(self):
"""Test if Error is raised when source directory does not exist."""
with self.assertRaises(FileNotFoundError):
publish(FIGS_AND_IDS, "not_existing_folder", DST_PATH, PIC_NAME)
publish(FIGS_AND_IDS, "not_existing_folder", DST_PATH)
def test_src_directory_type(self):
"""Test if Error is raised when source directory is not a string."""
with self.assertRaises(TypeError):
publish(FIGS_AND_IDS, [SRC_DIR, 4], DST_PATH, PIC_NAME)
publish(FIGS_AND_IDS, [SRC_DIR, 4], DST_PATH)
with self.assertRaises(TypeError):
publish(FIGS_AND_IDS, 4, DST_PATH, PIC_NAME)
publish(FIGS_AND_IDS, 4, DST_PATH)
def test_dst_directory(self):
"""
......@@ -132,7 +150,7 @@ class TestPublish(unittest.TestCase):
destination dir does not exist.
"""
with self.assertRaises(FileNotFoundError):
publish(FIGS_AND_IDS, SRC_DIR, "not_existing_folder/data", PIC_NAME)
publish(FIGS_AND_IDS, SRC_DIR, "not_existing_folder/data")
def test_script_exists(self):
"""
......@@ -158,8 +176,7 @@ class TestPublish(unittest.TestCase):
"from plotid.publish import publish\n"
"from plotid.plotoptions import PlotIDTransfer\n"
"publish(PlotIDTransfer(plt.figure(), 'testID2'),"
" 'test_src_folder', 'test_parent/test_dst_folder',"
" 'test_picture')",
" 'test_src_folder', 'test_parent/test_dst_folder')",
],
capture_output=True,
check=True,
......@@ -172,8 +189,7 @@ class TestPublish(unittest.TestCase):
"from plotid.publish import publish\n"
"from plotid.plotoptions import PlotIDTransfer\n"
"publish(PlotIDTransfer(plt.figure(), 'testID2'), "
"'test_src_folder', 'test_parent/test_dst_folder', "
"'test_picture')",
"'test_src_folder', 'test_parent/test_dst_folder')",
],
capture_output=True,
)
......@@ -199,9 +215,7 @@ class TestPublish(unittest.TestCase):
os.mkdir(os.path.join(DST_PATH, IDS_AS_LIST[0]))
# Mock user input as 'yes'
with patch("builtins.input", return_value="yes"):
publish(
FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME, data_storage="individual"
)
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, data_storage="individual")
# Skip test if tests are run from command line.
@unittest.skipIf(
......@@ -221,7 +235,7 @@ class TestPublish(unittest.TestCase):
# Mock user input as 'no'
with patch("builtins.input", return_value="no"):
with self.assertRaises(RuntimeError):
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME)
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH)
# Skip test if tests are run from command line.
@unittest.skipIf(
......@@ -241,9 +255,7 @@ class TestPublish(unittest.TestCase):
# Mock user input as empty (no should be default).
with patch("builtins.input", return_value=""):
with self.assertRaises(RuntimeError):
publish(
FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME, data_storage="individual"
)
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, data_storage="individual")
# Skip test if tests are run from command line.
@unittest.skipIf(
......@@ -264,7 +276,7 @@ class TestPublish(unittest.TestCase):
# Mock user input as 'yes' for deleting the partial copied data
with patch("builtins.input", side_effect=["yes", "yes"]):
with self.assertRaises(RuntimeError):
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME)
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, plot_names=PIC_NAME)
assert not os.path.isdir(invisible_path1)
os.remove("test_picture1.tmp.png")
os.remove("test_picture2.tmp.png")
......@@ -284,16 +296,12 @@ class TestPublish(unittest.TestCase):
"""
with self.assertRaises(ValueError):
publish(
FIGS_AND_IDS,
SRC_DIR,
DST_PATH,
PIC_NAME,
data_storage="none_existing_method",
FIGS_AND_IDS, SRC_DIR, DST_PATH, data_storage="none_existing_method"
)
with self.assertRaises(TypeError):
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME, data_storage=3)
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, data_storage=3)
with self.assertRaises(TypeError):
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME, data_storage=[])
publish(FIGS_AND_IDS, SRC_DIR, DST_PATH, data_storage=[])
def test_str(self):
"""
......@@ -301,7 +309,7 @@ class TestPublish(unittest.TestCase):
correct.
"""
self.maxDiff = None
publish_obj = PublishOptions(FIGS_AND_IDS, SRC_DIR, DST_PATH, PIC_NAME)
publish_obj = PublishOptions(FIGS_AND_IDS, SRC_DIR, DST_PATH)
self.assertIn(
"<class 'plotid.publish.PublishOptions'>: {'figure': "
"[<Figure size 640x480 with 0 Axes>, <Figure size"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment