plot: accept any viable target in dvc repo (#4602)

This commit is contained in:
Paweł Redzyński
2020-09-23 17:02:12 +03:00
committed by GitHub
parent 38dd1c9fe7
commit e1b34442aa
2 changed files with 83 additions and 17 deletions
+29 -16
View File
@@ -1,8 +1,10 @@
import logging
import os
from funcy import first, project
from dvc.exceptions import DvcException, NoPlotsError, OutputNotFoundError
from dvc.exceptions import DvcException, NoPlotsError
from dvc.path_info import PathInfo
from dvc.schema import PLOT_PROPS
from dvc.tree.repo import RepoTree
from dvc.utils import relpath
@@ -142,23 +144,34 @@ class Plots:
def _collect_plots(repo, targets=None, rev=None):
def _targets_to_outs(targets):
for t in targets:
try:
(out,) = repo.find_outs_by_path(t)
yield out
except OutputNotFoundError:
logger.warning(
"File '{}' was not found at: '{}'. It will not be "
"plotted.".format(t, rev)
)
plots = {out for stage in repo.stages for out in stage.outs if out.plot}
if targets:
outs = _targets_to_outs(targets)
else:
outs = (out for stage in repo.stages for out in stage.outs if out.plot)
def to_result(plots):
return {plot.path_info: _plot_props(plot) for plot in plots}
return {out.path_info: _plot_props(out) for out in outs}
if not targets:
return to_result(plots)
target_infos = {PathInfo(os.path.abspath(target)) for target in targets}
target_plots = set()
for p in plots:
if p.path_info in target_infos:
target_plots.add(p)
target_infos.remove(p.path_info)
tree = RepoTree(repo)
result = to_result(target_plots)
for t in target_infos:
if tree.isfile(t):
result[t] = {}
else:
logger.warning(
"'%s' was not found at: '%s'. It will not be plotted.", t, rev,
)
return result
def _plot_props(out):
+54 -1
View File
@@ -330,7 +330,7 @@ def test_plot_even_if_metric_missing(
with caplog.at_level(logging.WARNING, "dvc"):
plots = dvc.plots.show(revs=["v1", "v2"], targets=["metric.json"])
assert (
"File 'metric.json' was not found at: 'v1'. "
"'metric.json' was not found at: 'v1'. "
"It will not be plotted." in caplog.text
)
@@ -602,3 +602,56 @@ def test_multiple_plots(tmp_dir, scm, dvc, run_copy_metrics):
)
assert len(dvc.plots.show().keys()) == 2
def test_show_non_plot(tmp_dir, scm, dvc):
metric = [
{"first_val": 100, "val": 2},
{"first_val": 200, "val": 3},
]
_write_json(tmp_dir, metric, "metric.json")
plot_string = dvc.plots.show(targets=["metric.json"])["metric.json"]
plot_content = json.loads(plot_string)
assert plot_content["data"]["values"] == [
{
"val": 2,
PlotData.INDEX_FIELD: 0,
"first_val": 100,
"rev": "workspace",
},
{
"val": 3,
PlotData.INDEX_FIELD: 1,
"first_val": 200,
"rev": "workspace",
},
]
assert plot_content["encoding"]["x"]["field"] == PlotData.INDEX_FIELD
assert plot_content["encoding"]["y"]["field"] == "val"
def test_show_non_plot_and_plot_with_params(
tmp_dir, scm, dvc, run_copy_metrics
):
metric = [
{"first_val": 100, "val": 2},
{"first_val": 200, "val": 3},
]
_write_json(tmp_dir, metric, "metric.json")
run_copy_metrics(
"metric.json", "metric2.json", plots_no_cache=["metric2.json"]
)
dvc.plots.modify("metric2.json", props={"title": "TITLE"})
result = dvc.plots.show(targets=["metric.json", "metric2.json"])
plot_content = json.loads(result["metric.json"])
plot2_content = json.loads(result["metric2.json"])
assert plot2_content["title"] == "TITLE"
assert plot_content != plot2_content
plot_content.pop("title")
plot2_content.pop("title")
assert plot_content == plot2_content