# Error when rendering two images for classification

**URL:** <https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490>\
**Category:** Uncategorized\
**Tags:** image, front-end, solved\
**Created:** [January 30, 2025, 9:08am UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490 "2025-01-30T09:08:07Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tuomo\_h](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tuomo_h/32/4554_2.png) [@tuomo\_h](https://support.prodi.gy/u/tuomo_h)\
**Post date:** [January 30, 2025, 9:08am UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/1 "2025-01-30T09:08:07Z")

</div>

Hi!

I'm slowly getting familiar with Prodigy: the first task I want to do is to classify pairs of images and to make a binary choice (Yes/No) about them.

My input data looks like this:

```python
{"image_1": "https://s3_bucket_url/0.png", "image_2": "https://s3_bucket_url/1.png"}

```

And here's my task definition, which builds on previous posts on this forum:

```python
import prodigy
from prodigy.components.loaders import JSONL

@prodigy.recipe('classify-two-images')
def classify_images(dataset, path_to_jsonl):

    stream = JSONL(path_to_jsonl)

    blocks = [
        {'view_id': 'html'},
        {'view_id': 'choice', 'text': None, 'choice_style': 'single', 'choice_auto_accept': True}
    ]

    html_template = (
        '<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 2rem">'
        '<div style="font-family: monospace; white-space: pre-wrap; border-right: 1px solid #ccc"> {{image_1}} </div>'
        '<div> {{image_2}} </div>'
        '</div>'
    )

    return {'dataset': dataset,
            'stream': stream,
            'view_id': 'blocks',
            'config': {'blocks': blocks,
                       'html_template': html_template}
            }

```

I can launch the annotation task, but the data is not displayed due to the following error message:

 ![Screenshot 2025-01-30 at 11.06.57](https://us1.discourse-cdn.com/flex020/uploads/prodigy/original/2X/b/b520b16290c05c7ab7edc6b3b020b613f6a3639f.png)

Any ideas what I am doing wrong here?

---

<div class="post-metadata">

**Author:** ![magdaaniol](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/magdaaniol/32/2787_2.png) [@magdaaniol](https://support.prodi.gy/u/magdaaniol)\
**Post date:** [January 30, 2025, 10:48am UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/2 "2025-01-30T10:48:50Z")

</div>

Hi @tuomo_h,

It looks like the `choice` UI used as a component of your `blocks` is missing the list of options to choose from.  
Each task sent to `choice` should contain the `options` field with the following format:

```python
{
  "text": "Pick the odd one out.",
  "options": [
    {"id": 1, "text": "🍌 banana"},
    {"id": 2, "text": "🥦 broccoli"},
    {"id": 3, "text": "🍅 tomato"}
  ]
}

```

(btw. whenever you are doubt you can find the documentation of the JSONL format requirements for all UIs in our [Annotation Interfaces](https://prodi.gy/docs/api-interfaces) doc section)

The most convenient way to add `options` programmatically to your stream of tasks would be by [applying](https://prodi.gy/docs/api-components#stream.apply) a wrapper function to the stream. This way you can preserve the benefits of stream being a generator-like data structure ([StreamType](https://prodi.gy/docs/api-components#stream)). However, to be able to use `apply`, we need to load the stream via Prodigy [`get_stream`](https://prodi.gy/docs/api-components#stream.get_stream) function (JSONL loader is completely valid, but a newer and recommended way is to load the data source is via `get_stream` :

```python
from prodigy.components.stream import get_stream
from prodigy.types import StreamType

def add_options(stream: StreamType) -> StreamType:
    for eg in stream:
        eg["options"] = [
            {"id": 1, "text": "🍌 banana"},
            {"id": 2, "text": "🥦 broccoli"},
            {"id": 3, "text": "🍅 tomato"}
        ]
        yield eg
stream = get_stream(path_to_jsonl)
stream.apply(add_options, stream=stream)

```

This should eliminate the input task validation error you see in the UI.

---

<div class="post-metadata">

**Author:** ![tuomo\_h](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tuomo_h/32/4554_2.png) [@tuomo\_h](https://support.prodi.gy/u/tuomo_h)\
**Post date:** [January 30, 2025, 12:43pm UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/3 "2025-01-30T12:43:13Z")

</div>

Thanks for your help @magdaaniol – I managed to solve the problem!

I switched to `get_stream` and the classification interface, as it seems to be better suited for binary classification.

Also, I noticed a few errors in my HTML template, which were missing the `<img>` elements. I've added them below with a fixed with of 300 pixels for each image:

```python
html_template = (
    '<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 2rem">'
    '<div style="font-family: monospace; white-space: pre-wrap; border-right: 1px solid #ccc"> <img src="{{image_1}}" width=300/></div>'
    '<div> <img src="{{image_2}}" width=300/> </div>'
    '</div>'
    )

```

A follow-up question: is there a way to automatically resize the div element so that it would take up e.g. 80% of the screen width available in the "main window" where data is displayed?

---

<div class="post-metadata">

**Author:** ![magdaaniol](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/magdaaniol/32/2787_2.png) [@magdaaniol](https://support.prodi.gy/u/magdaaniol)\
**Post date:** [January 30, 2025, 4:26pm UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/4 "2025-01-30T16:26:05Z")

</div>

Hi @tuomo_h,

Of course `classification` UI is a better option for binary annotation - sorry I totally missed that 🙈 Hopefully the info on options will be useful for the future 🙂

As for the width, I'm not entirely sure which part would you like to make it 80% of its parent:

 ![containers](https://us1.discourse-cdn.com/flex020/uploads/prodigy/original/2X/1/1bc901522ed03363342d69de329a7948e089847c.jpeg)  
Taking the above image as a reference, I understand that you want your custom div to occupy 80% of the Prodigy card so that it smaller than it currently is?  
Or is it that you'd like the Prodigy card to take up 80% of the Prodigy content container?

---

<div class="post-metadata">

**Author:** ![tuomo\_h](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tuomo_h/32/4554_2.png) [@tuomo\_h](https://support.prodi.gy/u/tuomo_h)\
**Post date:** [January 30, 2025, 4:36pm UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/5 "2025-01-30T16:36:18Z")

</div>

Sorry, I'm still lacking the vocabulary for Prodigy UI components! To clarify:

1. I would like to have the width of Prodigy card to be 80% of the content window.
2. The images, in turn, would be dynamically sized so that they fit side-by-side in the custom div.

---

<div class="post-metadata">

**Author:** ![magdaaniol](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/magdaaniol/32/2787_2.png) [@magdaaniol](https://support.prodi.gy/u/magdaaniol)\
**Post date:** [February 3, 2025, 2:26pm UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/6 "2025-02-03T14:26:18Z")

</div>

No worries @tuomo_h! Now it's all clear!

To set the Prodigy card width, you can use `cardMaxWidth` property of the `custom_theme` setting in your prodigy json file:

```json
{"custom_theme": {
    "cardMaxWidth": "80%"
    }
}

```

This should make sure that the card will take up to 80% of the parent container whenever possible.  
Other `custom_theme` options are documented [here](https://prodi.gy/docs/api-web-app#themes) in case you're interested what other css "shortcuts" are available.

As for the image container, the styling of the parent container looks appropriate to me. I changed the fixed width of the immediate image container to `max-width: 100%; height: auto` to make sure it resizes automatically.  
I also implemented the vertical divider as a separate div to make sure it always appears in the middle of the gap.  
This result should be something like this (it should look the same on mobile devices as well):  
 ![images](https://us1.discourse-cdn.com/flex020/uploads/prodigy/original/2X/6/633674b5de5bc93f1dfc9082efcfcc9fb4277be5.gif)  
And here's the template I used:

```python
html_template = (
    '<div style="position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem">'
    '<div>'
    '<img src="{{image_1}}" style="max-width: 100%; height: auto"/>'
    '</div>'
    '<div style="position: absolute;left: 50%;top: 0;bottom: 0;width: 2px;background-color: #ccc;transform: translateX(-50%); z-index: 1;">'
    '</div>'
    '<div>'
    '<img src="{{image_2}}" style="max-width: 100%; height: auto"/>'
    '</div>'
    '</div>')

```

We could also make the images occupy the entire available space but that might lead to poor resolution in the case of smaller images.

---

<div class="post-metadata">

**Author:** ![tuomo\_h](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tuomo_h/32/4554_2.png) [@tuomo\_h](https://support.prodi.gy/u/tuomo_h)\
**Post date:** [February 3, 2025, 7:57pm UTC](https://support.prodi.gy/t/error-when-rendering-two-images-for-classification/7490/7 "2025-02-03T19:57:08Z")

</div>

@magdaaniol Thank you for the informative reply – I'm learning a lot here!
