Use Artifacts API to create a new Plot notebook downstream of a workflow
With the Plots Artifacts API, your Latch workflow can generate a new notebook from a standard Plot template and automatically populate it with parameters and outputs from earlier steps in your pipeline.
For example, in the video below, a DESeq2 workflow execution outputs a Plots Artifact on Latch Data with all the notebook parameters filled out. This eliminates the need for manual parameter entry by scientists, thereby minimizing rooms for errors.
Every Plot notebook is backed by a dedicated computer. To save costs, this new computer is only spun up when the end user double-clicks on the Artifact on Latch Data for the first time.
from latch.types.plots import PlotsArtifactBindings, PlotsArtifactTemplate, PlotsArtifact, Widgetartifact = PlotsArtifact( bindings=PlotsArtifactBindings( plot_templates=[ PlotsArtifactTemplate( template_id="1234", ## The Plot template ID widgets=[ Widget( transform_id="1234", ## The Python transform ID key="1", ## The `key` of the widget that we want to populate value="Value" ## Value to populate that widget with ) ], ) ] ))
To fill out the PlotsArtifactTemplate dataclass, we need to define four things:
The plot template ID
The ID of the Python transform cell that contains the widget
The unique ID of the widget (as one Python transform cell may contain many widgets)
Pro-tip: Not all the widgets in your original template have explicitly defined keys. If not, the key value is the order of the widget in that cell.
Example: Let’s say a Python transform cell has three widgets:
widget 1: (no key) => Key value is “0”
widget 2: (key = “k”) => Key value is “k”
widget 3: (no key) => Key value is “1”
Next, dump the dataclass into a JSON file and upload it to Latch Data.
Example 1: Inside a Jupyter notebook
Copy
...from latch.ldata.path import LPath# Convert the dataclass to a dictionaryartifact_dict = asdict(artifact)# Write it to a JSON filewith open("artifact.json", "w") as f: json.dump(artifact_dict, f, indent=2)latch_path = LPath("latch:///artifact.json")latch_path.upload_from("artifact.json")
Example 2: Inside a Latch workflow
Copy
from latch.types.plots import PlotsArtifactBindings, PlotsArtifactTemplate, PlotsArtifact, Widget@small_taskdef my_task(output_dir: LatchDir) -> LatchFile: artifact = PlotsArtifact( bindings=PlotsArtifactBindings( plot_templates=[ PlotsArtifactTemplate( template_id="46", ## The Plot template ID widgets=[ Widget( transform_id="1234", ## The Python transform ID key="input_1", ## The `key` of the widget that we want to populate value="petal.width" ## Value to populate that widget with ) ], ) ] ) )# Convert the dataclass to a dictionaryartifact_dict = asdict(artifact)# Write it to a JSON filewith open("artifact.json", "w") as f: json.dump(artifact_dict, f, indent=2)# You need to return a file artifact for the workflowreturn LatchFile(output_path, f"{output_dir.remote_path}/artifact.json")