prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  [docs] Add a visualization of the example script in the README
  While the readme specifies how you can use the example script, it does not show any visualization examples. We could easily add one to help users.
  
  </issue>
  <code>
  [start of doctr/utils/visualization.py]
  1 # Copyright (C) 2021, Mindee.
  2 
  3 # This program is licensed under the Apache License version 2.
  4 # See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.
  5 
  6 import matplotlib.pyplot as plt
  7 import matplotlib.patches as patches
  8 import mplcursors
  9 import numpy as np
  10 from typing import Tuple, List, Dict, Any
  11 
  12 from .common_types import BoundingBox
  13 
  14 __all__ = ['visualize_page']
  15 
  16 
  17 def create_patch(
  18     geometry: BoundingBox,
  19     label: str,
  20     page_dimensions: Tuple[int, int],
  21     color: Tuple[int, int, int],
  22     alpha: float = 0.3,
  23     linewidth: int = 2,
  24 ) -> patches.Patch:
  25     """Create a matplotlib patch (rectangle) bounding the element
  26 
  27     Args:
  28         geometry: bounding box of the element
  29         label: label to display when hovered
  30         page_dimensions: dimensions of the Page
  31         color: color to draw box
  32         alpha: opacity parameter to fill the boxes, 0 = transparent
  33         linewidth: line width
  34 
  35     Returns:
  36         a rectangular Patch
  37     """
  38     h, w = page_dimensions
  39     (xmin, ymin), (xmax, ymax) = geometry
  40     xmin, xmax = xmin * w, xmax * w
  41     ymin, ymax = ymin * h, ymax * h
  42     rect = patches.Rectangle(
  43         (xmin, ymin),
  44         xmax - xmin,
  45         ymax - ymin,
  46         fill=True,
  47         linewidth=linewidth,
  48         edgecolor=(*color, alpha),
  49         facecolor=(*color, alpha),
  50         label=label
  51     )
  52     return rect
  53 
  54 
  55 def visualize_page(
  56     page: Dict[str, Any],
  57     image: np.ndarray,
  58     words_only: bool = True,
  59 ) -> None:
  60     """Visualize a full page with predicted blocks, lines and words
  61 
  62     Example::
  63         >>> import numpy as np
  64         >>> import matplotlib.pyplot as plt
  65         >>> from doctr.utils.visualization import visualize_page
  66         >>> from doctr.models import ocr_db_crnn
  67         >>> model = ocr_db_crnn(pretrained=True)
  68         >>> input_page = (255 * np.random.rand(600, 800, 3)).astype(np.uint8)
  69         >>> out = model([[input_page]])
  70         >>> visualize_page(out[0].pages[0].export(), input_page)
  71         >>> plt.show()
  72 
  73     Args:
  74         page: the exported Page of a Document
  75         image: np array of the page, needs to have the same shape than page['dimensions']
  76         words_only: whether only words should be displayed
  77     """
  78     # Display the image
  79     _, ax = plt.subplots()
  80     ax.imshow(image)
  81     # hide both axis
  82     ax.axis('off')
  83 
  84     artists: List[patches.Patch] = []  # instantiate an empty list of patches (to be drawn on the page)
  85 
  86     for block in page['blocks']:
  87         if not words_only:
  88             rect = create_patch(block['geometry'], 'block', page['dimensions'], (0, 1, 0), linewidth=1)
  89             # add patch on figure
  90             ax.add_patch(rect)
  91             # add patch to cursor's artists
  92             artists.append(rect)
  93 
  94         for line in block['lines']:
  95             if not words_only:
  96                 rect = create_patch(line['geometry'], 'line', page['dimensions'], (1, 0, 0), linewidth=1)
  97                 ax.add_patch(rect)
  98                 artists.append(rect)
  99 
  100             for word in line['words']:
  101                 rect = create_patch(word['geometry'], f"{word['value']} (confidence: {word['confidence']:.2%})",
  102                                     page['dimensions'], (0, 0, 1))
  103                 ax.add_patch(rect)
  104                 artists.append(rect)
  105 
  106         if not words_only:
  107             for artefact in block['artefacts']:
  108                 rect = create_patch(artefact['geometry'], 'artefact', page['dimensions'], (0.5, 0.5, 0.5), linewidth=1)
  109                 ax.add_patch(rect)
  110                 artists.append(rect)
  111 
  112     # Create mlp Cursor to hover patches in artists
  113     mplcursors.Cursor(artists, hover=2).connect("add", lambda sel: sel.annotation.set_text(sel.artist.get_label()))
  114
  [end of doctr/utils/visualization.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/doctr/utils/visualization.py b/doctr/utils/visualization.py
  --- a/doctr/utils/visualization.py
  +++ b/doctr/utils/visualization.py
  @@ -56,6 +56,7 @@
       page: Dict[str, Any],
       image: np.ndarray,
       words_only: bool = True,
  +    scale: float = 10,
   ) -> None:
       """Visualize a full page with predicted blocks, lines and words
   
  @@ -74,9 +75,13 @@
           page: the exported Page of a Document
           image: np array of the page, needs to have the same shape than page['dimensions']
           words_only: whether only words should be displayed
  +        scale: figsize of the largest windows side
       """
  +    # Get proper scale and aspect ratio
  +    h, w = image.shape[:2]
  +    size = (scale * w / h, scale) if h > w else (scale, h / w * scale)
  +    fig, ax = plt.subplots(figsize=size)
       # Display the image
  -    _, ax = plt.subplots()
       ax.imshow(image)
       # hide both axis
       ax.axis('off')
  @@ -111,3 +116,4 @@
   
       # Create mlp Cursor to hover patches in artists
       mplcursors.Cursor(artists, hover=2).connect("add", lambda sel: sel.annotation.set_text(sel.artist.get_label()))
  +    fig.tight_layout()
  
verification_info: {"golden_diff": "diff --git a/doctr/utils/visualization.py b/doctr/utils/visualization.py\n--- a/doctr/utils/visualization.py\n+++ b/doctr/utils/visualization.py\n@@ -56,6 +56,7 @@\n     page: Dict[str, Any],\n     image: np.ndarray,\n     words_only: bool = True,\n+    scale: float = 10,\n ) -> None:\n     \"\"\"Visualize a full page with predicted blocks, lines and words\n \n@@ -74,9 +75,13 @@\n         page: the exported Page of a Document\n         image: np array of the page, needs to have the same shape than page['dimensions']\n         words_only: whether only words should be displayed\n+        scale: figsize of the largest windows side\n     \"\"\"\n+    # Get proper scale and aspect ratio\n+    h, w = image.shape[:2]\n+    size = (scale * w / h, scale) if h > w else (scale, h / w * scale)\n+    fig, ax = plt.subplots(figsize=size)\n     # Display the image\n-    _, ax = plt.subplots()\n     ax.imshow(image)\n     # hide both axis\n     ax.axis('off')\n@@ -111,3 +116,4 @@\n \n     # Create mlp Cursor to hover patches in artists\n     mplcursors.Cursor(artists, hover=2).connect(\"add\", lambda sel: sel.annotation.set_text(sel.artist.get_label()))\n+    fig.tight_layout()\n", "issue": "[docs] Add a visualization of the example script in the README\nWhile the readme specifies how you can use the example script, it does not show any visualization examples. We could easily add one to help users.\n", "before_files": [{"content": "# Copyright (C) 2021, Mindee.\n\n# This program is licensed under the Apache License version 2.\n# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.\n\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport mplcursors\nimport numpy as np\nfrom typing import Tuple, List, Dict, Any\n\nfrom .common_types import BoundingBox\n\n__all__ = ['visualize_page']\n\n\ndef create_patch(\n    geometry: BoundingBox,\n    label: str,\n    page_dimensions: Tuple[int, int],\n    color: Tuple[int, int, int],\n    alpha: float = 0.3,\n    linewidth: int = 2,\n) -> patches.Patch:\n    \"\"\"Create a matplotlib patch (rectangle) bounding the element\n\n    Args:\n        geometry: bounding box of the element\n        label: label to display when hovered\n        page_dimensions: dimensions of the Page\n        color: color to draw box\n        alpha: opacity parameter to fill the boxes, 0 = transparent\n        linewidth: line width\n\n    Returns:\n        a rectangular Patch\n    \"\"\"\n    h, w = page_dimensions\n    (xmin, ymin), (xmax, ymax) = geometry\n    xmin, xmax = xmin * w, xmax * w\n    ymin, ymax = ymin * h, ymax * h\n    rect = patches.Rectangle(\n        (xmin, ymin),\n        xmax - xmin,\n        ymax - ymin,\n        fill=True,\n        linewidth=linewidth,\n        edgecolor=(*color, alpha),\n        facecolor=(*color, alpha),\n        label=label\n    )\n    return rect\n\n\ndef visualize_page(\n    page: Dict[str, Any],\n    image: np.ndarray,\n    words_only: bool = True,\n) -> None:\n    \"\"\"Visualize a full page with predicted blocks, lines and words\n\n    Example::\n        >>> import numpy as np\n        >>> import matplotlib.pyplot as plt\n        >>> from doctr.utils.visualization import visualize_page\n        >>> from doctr.models import ocr_db_crnn\n        >>> model = ocr_db_crnn(pretrained=True)\n        >>> input_page = (255 * np.random.rand(600, 800, 3)).astype(np.uint8)\n        >>> out = model([[input_page]])\n        >>> visualize_page(out[0].pages[0].export(), input_page)\n        >>> plt.show()\n\n    Args:\n        page: the exported Page of a Document\n        image: np array of the page, needs to have the same shape than page['dimensions']\n        words_only: whether only words should be displayed\n    \"\"\"\n    # Display the image\n    _, ax = plt.subplots()\n    ax.imshow(image)\n    # hide both axis\n    ax.axis('off')\n\n    artists: List[patches.Patch] = []  # instantiate an empty list of patches (to be drawn on the page)\n\n    for block in page['blocks']:\n        if not words_only:\n            rect = create_patch(block['geometry'], 'block', page['dimensions'], (0, 1, 0), linewidth=1)\n            # add patch on figure\n            ax.add_patch(rect)\n            # add patch to cursor's artists\n            artists.append(rect)\n\n        for line in block['lines']:\n            if not words_only:\n                rect = create_patch(line['geometry'], 'line', page['dimensions'], (1, 0, 0), linewidth=1)\n                ax.add_patch(rect)\n                artists.append(rect)\n\n            for word in line['words']:\n                rect = create_patch(word['geometry'], f\"{word['value']} (confidence: {word['confidence']:.2%})\",\n                                    page['dimensions'], (0, 0, 1))\n                ax.add_patch(rect)\n                artists.append(rect)\n\n        if not words_only:\n            for artefact in block['artefacts']:\n                rect = create_patch(artefact['geometry'], 'artefact', page['dimensions'], (0.5, 0.5, 0.5), linewidth=1)\n                ax.add_patch(rect)\n                artists.append(rect)\n\n    # Create mlp Cursor to hover patches in artists\n    mplcursors.Cursor(artists, hover=2).connect(\"add\", lambda sel: sel.annotation.set_text(sel.artist.get_label()))\n", "path": "doctr/utils/visualization.py"}]}