Skip to content

Commit

Permalink
Correctly merge field_df and region_df (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
hoxbro authored Sep 20, 2023
1 parent 1615a2a commit 11f9842
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 13 deletions.
30 changes: 17 additions & 13 deletions holonote/annotate/annotator.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,28 @@ def ranges_1d(cls, region_df, field_df, invert_axes=False, extra_params=None):

@classmethod
def _range_indicators(cls, region_df, field_df, dimensionality, invert_axes=False, extra_params=None):
rect_data = []
# TODO: Clean this up VSpans/HSpans/VLines/HLines
index_col_name = 'id' if field_df.index.name is None else field_df.index.name

mdata_vals = ([None] * len(region_df['_id'])
if len(field_df.columns)==0 else field_df.to_dict('records'))
for id_val, value, mdata in zip(region_df['_id'], region_df["value"], mdata_vals):
if dimensionality=='1d':
coords = (value[0], extra_params['rect_min'], value[1], extra_params['rect_max'])
else:
coords = (value[0], value[2], value[1], value[3]) # LBRT format
if region_df.empty:
return hv.Rectangles([], vdims=[*field_df.columns, index_col_name])

if None in coords: continue
data = region_df.merge(field_df, left_on="_id", right_index=True)
values = pd.DataFrame.from_records(data["value"])
id_vals = data["_id"].rename({"_id": index_col_name})
mdata_vals = data[field_df.columns]

mdata_tuple = () if len(field_df.columns)==0 else tuple(mdata.values())
rect_data.append(coords + mdata_tuple + (id_val,))
# TODO: Add check for None, (None, None), or (None, None, None, None) in values?

index_col_name = ['id'] if field_df.index.name is None else [field_df.index.name]
return hv.Rectangles(rect_data, vdims=list(field_df.columns)+index_col_name) # kdims?
if dimensionality=='1d':
coords = values[[0, 0, 1, 1]].copy()
coords.iloc[:, 1] = extra_params["rect_min"]
coords.iloc[:, 3] = extra_params["rect_max"]
else:
coords = values[[0, 2, 1, 3]] # LBRT format

rect_data = list(pd.concat([coords, mdata_vals, id_vals], axis=1).itertuples(index=False))
return hv.Rectangles(rect_data, vdims=[*field_df.columns, index_col_name]) # kdims?


class AnnotatorInterface(param.Parameterized):
Expand Down
46 changes: 46 additions & 0 deletions holonote/tests/test_indicators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import numpy as np
import pandas as pd

from holonote.annotate.annotator import Indicator


def test_range2d_id_matches() -> None:
value = np.arange(8).reshape(2, 4)
region_df = pd.DataFrame({"value": list(value), "_id": ["A", "B"]})
field_df = pd.DataFrame(["B", "A"], index=["B", "A"], columns=["description"])

# id and description should match
output = Indicator.ranges_2d(region_df, field_df).data
expected = pd.DataFrame(
{
"x0": {0: 0, 1: 4},
"y0": {0: 2, 1: 6},
"x1": {0: 1, 1: 5},
"y1": {0: 3, 1: 7},
"description": {0: "A", 1: "B"},
"id": {0: "A", 1: "B"},
}
)
pd.testing.assert_frame_equal(output, expected)


def test_range1d_id_matches() -> None:
value = np.arange(4).reshape(2, 2)
region_df = pd.DataFrame({"value": list(value), "_id": ["A", "B"]})
field_df = pd.DataFrame(["B", "A"], index=["B", "A"], columns=["description"])

# id and description should match
output = Indicator.ranges_1d(
region_df, field_df, extra_params={"rect_min": -2, "rect_max": -2}
).data
expected = pd.DataFrame(
{
"x0": {0: 0, 1: 2},
"y0": {0: -2, 1: -2},
"x1": {0: 1, 1: 3},
"y1": {0: -2, 1: -2},
"description": {0: "A", 1: "B"},
"id": {0: "A", 1: "B"},
}
)
pd.testing.assert_frame_equal(output, expected)

0 comments on commit 11f9842

Please sign in to comment.