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

Adds fugue integration #1102

Merged
merged 6 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions hvplot/fugue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""
Experimental support for fugue.
"""
from typing import Any, Dict, Tuple

import panel as _pn

from . import hvPlotTabular, post_patch
from .util import _fugue_ipython

def patch(name="hvplot", extension="bokeh", logo=False):
try:
from fugue import DataFrames, Outputter
from fugue.extensions import namespace_candidate, parse_outputter
except:
raise ImportError(
'Could not add fugue support as it could not be imported. '
'Please make sure you have installed fugue in your environment.'
)

import hvplot.pandas # noqa: F401

class _Visualize(Outputter):
def __init__(self, func: str) -> None:
super().__init__()
self._func = func
getattr(hvPlotTabular, func) # ensure the func exists

def process(self, dfs: DataFrames) -> None:
"""
Process the dataframes and output the result as
a pn.Column.

Parameters:
-----------
dfs: fugue.DataFrames
"""
charts = []
for df in dfs.values():
params = dict(self.params)
opts: Dict[str, Any] = params.pop("opts", {})
chart = getattr(df.as_pandas().hvplot, self._func)(**params).opts(**opts)
charts.append(chart)
col = _pn.Column(*charts)
try:
if not _fugue_ipython:
get_ipython()
except NameError:
col.show() # in script
else:
from IPython.display import display
display(col) # in notebook


@parse_outputter.candidate(namespace_candidate(name, lambda x: isinstance(x, str)))
def _parse_hvplot(obj: Tuple[str, str]) -> Outputter:
return _Visualize(obj[1])

post_patch(extension, logo)


patch()
46 changes: 46 additions & 0 deletions hvplot/tests/testfugue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Fugue test suite"""

import hvplot
import pandas as pd
import pytest

# Patch required before importing hvplot.fugue
hvplot.util._fugue_ipython = True

try:
import fugue.api as fa
import hvplot.fugue # noqa: F401
except:
pytest.skip(allow_module_level=True)


@pytest.fixture
def table():
df = pd.DataFrame(
{
"g": ["a", "b", "a", "b", "a", "b"],
"x": [1, 2, 3, 4, 5, 6],
"y": [1, 2, 3, 4, 5, 6],
}
)
return df


def test_fugure_ipython_line(table, capsys):
"""hvplot works with Fugue"""
fa.fugue_sql(
"""
OUTPUT table USING hvplot:line(
x="x",
y="y",
by="g",
size=100,
opts={"width": 500, "height": 500}
)
"""
)
# Check that the output contains the following:
# Column
# [0] HoloViews(NdOverlay)
output = capsys.readouterr().out
assert output == 'Column\n [0] HoloViews(NdOverlay)\n'
2 changes: 1 addition & 1 deletion hvplot/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
bokeh_version = Version(bokeh.__version__)
bokeh3 = bokeh_version >= Version("3.0")
param2 = Version(param.__version__) >= Version("2.0rc4")

_fugue_ipython = None # To be set to True in tests to mock ipython

def with_hv_extension(func, extension='bokeh', logo=False):
"""If hv.extension is not loaded, load before calling function"""
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def get_setup_version(reponame):
'ipywidgets',
'dask',
'polars',
'fugue',
]

# Dependencies required to run the notebooks
Expand Down