Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for arbitrary Vega-Lite plots #569

Closed
alexk101 opened this issue May 15, 2023 · 10 comments
Closed

Add support for arbitrary Vega-Lite plots #569

alexk101 opened this issue May 15, 2023 · 10 comments

Comments

@alexk101
Copy link

alexk101 commented May 15, 2023

I am not entirely sure that this is a possible feature , as I feel it would have already been implemented if that were the case, but it would be nice to log any kind of vega-lite plot. Currently there exists the log_plot, but this is fairly limited by the requirements of DVC plot templates. For example, if I wanted to create a grouped bar plot, I could not with the current way in which values are injected.

{
  "title": {
    "text": "Classification Metrics",
    "anchor": "middle"
  },
  "encoding": {
    "column": {
      "field": "category",
      "header": {
        "orient": "bottom"
      }
    },
    "y": {
      "field": "macroF1",
      "type": "quantitative"
    },
    "x": {
      "field": "group",
      "axis": null
    },
    "color": {
      "field": "group"
    }
  },
  "config": {
    "view": {
      "stroke": "transparent"
    }
  },
  "mark": "bar",
  "data": {
    "values": [
      {
        "category": "feedback",
        "group": "deck",
        "macroF1": 0.2513221334131033
      },
      {
        "category": "feedback",
        "group": "deck shift",
        "macroF1": 0.250825352553961
      },
      {
        "category": "feedback",
        "group": "earliest quint",
        "macroF1": 0.204823556791436
      },
      {
        "category": "planning",
        "group": "deck",
        "macroF1": 0.2513221334131033
      },
      {
        "category": "planning",
        "group": "deck shift",
        "macroF1": 0.250825352553961
      },
      {
        "category": "planning",
        "group": "earliest quint",
        "macroF1": 0.204823556791436
      },
    ]
  }
}

This is a live view of the above plot. It may be the case that it is more appropriate to submit this as an issue on DVC, and not DVCLive, but I will put it here for now.

@daavoo
Copy link
Contributor

daavoo commented May 16, 2023

Hi @alexk101 , it is a little hidden in the docs, but it is possible to use custom vega templates in DVC as described in https://dvc.org/doc/command-reference/plots/templates#custom-templates .

So, for your example, the custom template would look as follows:

{
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "data": {
        "values": "<DVC_METRIC_DATA>"
    },
    "title": {"text": "<DVC_METRIC_TITLE>", "anchor": "middle"},
    "encoding": {
      "column": {"field": "category", "header": {"orient": "bottom"}},
      "y": {"field": "<DVC_METRIC_Y>", "type": "quantitative"},
      "x": {"field": "<DVC_METRIC_X>", "axis": null},
      "color": {"field": "<DVC_METRIC_X>"}
    },
    "config": {"view": {"stroke": "transparent"}},
    "mark": "bar"
}

Assuming it is saved in custom_template.json, you could reference it in your Python code:

from dvclive import Live

datapoints = [
    {"category": "feedback", "group": "deck", "macroF1": 0.2513221334131033},
    {
      "category": "feedback",
      "group": "deck shift",
      "macroF1": 0.250825352553961
    },
    {
      "category": "feedback",
      "group": "earliest quint",
      "macroF1": 0.204823556791436
    },
    {"category": "planning", "group": "deck", "macroF1": 0.2513221334131033},
    {
      "category": "planning",
      "group": "deck shift",
      "macroF1": 0.250825352553961
    },
    {
      "category": "planning",
      "group": "earliest quint",
      "macroF1": 0.204823556791436
    }
]

with Live(report=None) as live:
    live.log_plot(
        "custom_bar_plot", 
        datapoints, 
        x="group", y="macroF1", template="custom_template.json",
        title="Classification Metrics"
    )

And the plot should be rendered correctly:

$ dvc plots show

visualization

@alexk101
Copy link
Author

Ah, I see. My understanding of the parameters and how they are injected was a little off. This solves my problem. Thanks, @daavoo ! And I see this other issue you have added and agree with your points there.

@alexk101
Copy link
Author

alexk101 commented May 19, 2023

@daavoo I seem to have found another sticking point for my work. Does DVC not support the 'spec' field for vega lite? I am trying to do something similar to what I previously posted, but using a faceted plot.

{
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "repeat": ["quintile"],
    "config": {"view": {"stroke": "transparent"}},
    "spec": {
        "title": {"text": "<DVC_METRIC_TITLE>", "anchor": "middle"},
        "encoding": {
            "column": {"field": "category", "header": {"orient": "bottom"}},
            "row": {"field": "quintile", "title": "Quintile"},
            "y": {"field": "<DVC_METRIC_Y>", "type": "quantitative"},
            "x": {"field": "<DVC_METRIC_X>", "axis": null},
            "color": {"field": "<DVC_METRIC_X>"}
            },
        "mark": "bar",
        "data": {
            "values": "<DVC_METRIC_DATA>"
        }
    }
}

The structure of the plot is valid, as I have it displayed in the vega-lite editor here. When I try and plot this using DVCLive, it tells me that I am missing the '<DVC_METRIC_DATA'> anchor,

dvc_render.vega_templates.BadTemplateError: Template '../templates/multi_bar_summary.json' is not using '<DVC_METRIC_DATA>' anchor

though I am clearly including it. Is this some kind of issue with how templates are parsed or am I missing something else?

@dberenbaum
Copy link
Collaborator

dberenbaum commented May 19, 2023

@alexk101 Can you provide the output of dvc doctor? I'm able to generate a plot with that template:

visualization(4)

Sorry, that's obviously not the updated template 😄 . We will try to take a closer look as soon as we can.

@dberenbaum
Copy link
Collaborator

Okay, now I think I have the right template and it's working. Could you try pip install --upgrade dvc dvclive dvc-render?

visualization(6)

@alexk101
Copy link
Author

@dberenbaum Unfortunately still failing, though somewhere else now.

Stacktrace:

Traceback (most recent call last):
  File "/home/alexk101/Documents/Research/Bertenthal Lab/igt/igt-models/src/summarize.py", line 126, in <module>
    sys.exit(main())
  File "/home/alexk101/Documents/Research/Bertenthal Lab/igt/igt-models/src/summarize.py", line 119, in main
    summarize()
  File "/home/alexk101/Documents/Research/Bertenthal Lab/igt/igt-models/src/summarize.py", line 113, in summarize
    with Live(str(Path('../summary'))) as live:
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvclive/live.py", line 521, in __exit__
    self.end()
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvclive/live.py", line 499, in end
    self.make_report()
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvclive/live.py", line 462, in make_report
    make_report(self)
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvclive/report.py", line 173, in make_report
    render_html(renderers, live.report_file, refresh_seconds=5)
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/html.py", line 99, in render_html
    document.with_element(renderer.generate_html(html_path=output_path))
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/base.py", line 54, in generate_html
    partial = self.partial_html(html_path=html_path)
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/vega.py", line 94, in partial_html
    return self.get_filled_template()  # type: ignore
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/vega.py", line 78, in get_filled_template
    if not self.template.has_anchor(name):
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/vega_templates.py", line 123, in has_anchor
    found = dict_find_value(self.content, self.anchor(name))
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/vega_templates.py", line 73, in dict_find_value
    return any(dict_find_value(e, value) for e in v)
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/vega_templates.py", line 73, in <genexpr>
    return any(dict_find_value(e, value) for e in v)
  File "/home/alexk101/.mambaforge/envs/general/lib/python3.10/site-packages/dvc_render/vega_templates.py", line 65, in dict_find_value
    for v in d.values():
AttributeError: 'str' object has no attribute 'values'

DVC Doctor:

DVC version: 2.57.2 (pip)
-------------------------
Platform: Python 3.10.11 on Linux-6.3.2-arch1-1-x86_64-with-glibc2.37
Subprojects:
	dvc_data = 0.51.0
	dvc_objects = 0.22.0
	dvc_render = 0.5.2
	dvc_task = 0.2.1
	scmrepo = 1.0.3
Supports:
	http (aiohttp = 3.7.4.post0, aiohttp-retry = 2.8.3),
	https (aiohttp = 3.7.4.post0, aiohttp-retry = 2.8.3),
	ssh (sshfs = 2023.4.1)
Config:
	Global: /home/alexk101/.config/dvc
	System: /etc/xdg/dvc
Cache types: hardlink, symlink
Cache directory: ext4 on /dev/nvme0n1p7
Caches: local
Remotes: ssh
Workspace directory: ext4 on /dev/nvme0n1p7
Repo: dvc, git
Repo.site_cache_dir: /var/tmp/dvc/repo/140d32e21af9cdc540ba90f3896b4725

It seems to be getting stuck parsing the some part of the template that should be a dictionary, but is a string.

@alexk101
Copy link
Author

I found where the problem in dvc-render is. I am opening a pull request for the change. Will update when I am done.

@alexk101
Copy link
Author

iterative/dvc-render#134

@dberenbaum
Copy link
Collaborator

Nice, thank you for finding that bug! Sorry, I guess it was me who was using the outdated version 🤦 .

@daavoo
Copy link
Contributor

daavoo commented May 20, 2023

I think we can close this one and if something else comes up, open a new one here or in dvc-render.

Thanks @alexk101 !!

@daavoo daavoo closed this as completed May 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants