Open mspronesti opened 1 month ago
Thank you for reaching out with your question. You can achieve the desired functionality by using the visibleWhen
and when
attributes in your labeling configuration to conditionally display components based on the presence of data. This way, you can hide the padding entries where item_{i}_name
is empty.
Here's how you can modify your generate_label_config
function:
def generate_label_config(max_items): items = "" for i in range(max_items): items += f""" <View visibleWhen="not equal" when="$item_{i}_name" value=""> <Text name="item_{i}_name" value="$item_{i}_name" /> <Choices name="item_{i}_label" toName="item_{i}_name" choice="single" required="true" showInline="true"> <Choice value="0"/> <Choice value="1"/> <Choice value="2"/> </Choices> </View> """ return f""" <View> <Header value="Title: $title" /> <Header value="Items and Labels:" /> {items} </View> """
In this updated configuration:
<View>
tag that includes the visibleWhen
attribute.visibleWhen="not equal"
condition checks if the corresponding $item_{i}_name
is not equal to an empty string.If $item_{i}_name
is empty (i.e., a padding entry), the entire block for that item will be hidden in the labeling interface.
By implementing this, only the items with actual data will be displayed to the annotators, and the padding entries will remain hidden.
Example Explanation:
For your first task:
{ "data": { "title": "title0", "item_0_name": "a0", "item_0_label": "label0", "item_1_name": "a1", "item_1_label": "label1", "item_2_name": "", "item_2_label": "", "item_3_name": "", "item_3_label": "" }, "predictions": [{ "result": [ { "from_name": "item_0_label", "to_name": "item_0_name", "type": "choices", "value": {"choices": ["0"]} }, { "from_name": "item_1_label", "to_name": "item_1_name", "type": "choices", "value": {"choices": ["2"]} } ] } ]}
Since item_2_name
and item_3_name
are empty strings, the corresponding Views will be hidden, and only item_0
and item_1
will be displayed.
Additional Notes:
$item_{i}_name
and $item_{i}_label
are correctly populated in your data.visibleWhen
condition supports operators like equal
, not equal
, greater
, less
, contains
, etc., which you can use based on your needs.
Let me know if you have any further questions or need additional assistance!Thanks,
Tyler Conlee Head of Support HumanSignal
Comment by Tyler Conlee Workflow Run
Hi @heidi-humansignal,
unfortunately, your suggestion doesn't work for me.
Are you sure that "not equal"
is a valid value for visibleWhen
and that when
is a valid parameter? They don't seem to be mentioned anywhere in the docs.
Hello,
Thank you for bringing this to my attention, and I apologize for any confusion earlier. You are correct—the visibleWhen
attribute does not support operators like not_equal
or not equal
. Instead, visibleWhen
can only have the following values:
region-selected
no-region-selected
choice-selected
choice-unselected
Given this limitation, to conditionally display components based on whether a variable is empty, we can use dynamic rendering with the <List>
and <Template>
tags. This approach allows you to display only the items that are present in your data without padding or the need for conditional visibility.
<List>
and <Template>
TagsLabeling Configuration:
<View> <Header value="Title: $title" /> <Header value="Items and Labels:" /> <List name="item_list" value="$items"> <Template> <View> <Text name="item_name_$index" value="$item.name" /> <Choices name="item_label_$index" toName="item_name_$index" choice="single" required="true" showInline="true"> <Choice value="0" /> <Choice value="1" /> <Choice value="2" /> </Choices> </View> </Template> </List></View>
Task Data Format: Modify your task data to include an array of items:
{ "data": { "title": "title0", "items": [{"name": "a0"}, {"name": "a1"}] }, "predictions": [{ "result": [ { "from_name": "item_label_0", "to_name": "item_name_0", "type": "choices", "value": {"choices": ["0"]} }, { "from_name": "item_label_1", "to_name": "item_name_1", "type": "choices", "value": {"choices": ["2"]} } ] } ]}
<List>
Tag: Iterates over the $items
array in your task data.<Template>
Tag: Defines the structure for each item in the list.$index
ensures that each Text
and Choices
tag has a unique name
attribute.Ensure that your prediction JSON references the correct dynamically generated name
attributes using the $index
variable.
Here's how you might modify your script:
def generate_label_config(): return """ <View> <Header value="Title: $title" /> <Header value="Items and Labels:" /> <List name="item_list" value="$items"> <Template> <View> <Text name="item_name_$index" value="$item.name" /> <Choices name="item_label_$index" toName="item_name_$index" choice="single" required="true" showInline="true"> <Choice value="0" /> <Choice value="1" /> <Choice value="2" /> </Choices> </View> </Template> </List> </View> """if __name__ == '__main__': fake_data = [{ "data": { "title": "title0", "items": [ {"name": "a0"}, {"name": "a1"}] }, "predictions": [{ "result": [ { "from_name": "item_label_0", "to_name": "item_name_0", "type": "choices", "value": {"choices": ["0"]} }, { "from_name": "item_label_1", "to_name": "item_name_1", "type": "choices", "value": {"choices": ["2"]} } ] } ] }, { "data": { "title": "title1", "items": [{"name": "b0"}, {"name": "b1"}, {"name": "b2"}, {"name": "b3"}] }, "predictions": [{ "result": [ { "from_name": "item_label_0", "to_name": "item_name_0", "type": "choices", "value": {"choices": ["1"]} }, { "from_name": "item_label_1", "to_name": "item_name_1", "type": "choices": ["2"]} }, { "from_name": "item_label_2", "to_name": "item_name_2", "type": "choices", "value": {"choices": ["2"]} }, { "from_name": "item_label_3", "to_name": "item_name_3", "type": "choices", "value": {"choices": ["0"]} } ] } ] }, { "data": { "title": "title2", "items": [{"name": "c0"}] }, "predictions": [{ "result": [ { "from_name": "item_label_0", "to_name": "item_name_0", "type": "choices", "value": {"choices": ["0"]} } ] } ] } ] ls = Client(url='http://localhost:8080', api_key='API-KEY') label_config = generate_label_config() project = ls.start_project( title="Dynamic Items Project", label_config=label_config ) project.import_tasks(fake_data)
<List>
and <Template>
tags is part of Label Studio's dynamic labeling capabilities.Repeater
tag is deprecated and not recommended for use due to performance issues.Thank you, Abu
Comment by Abubakar Saad Workflow Run
Say I have a dataset of items of variable length and the list of their pre-annotations (0,1 or 2), e.g.
As it seems like that the label configuration has to be of fixed length, I am computing the maximum length of the
item
entry and adding some empty "padding entries". However, hiding them using a condition such asname == ''
would be nice.Here's a minimal reproducible example: