We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] zmin and zmax not working in imshow for 2d data
See for example
```
import plotly.express as px
import numpy as np
img = np.random.random((10, 10))
px.imshow(img, zmin=0.3, zmax=0.7)
```
I think this is because the Heatmap trace uses instead the `range_color` argument which was quite introduced quite late in the process. It's easy to fix, we just have to decide first if the API is ok as it is. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `packages/python/plotly/plotly/express/_imshow.py`
Content:
```
1 import plotly.graph_objs as go
2 from _plotly_utils.basevalidators import ColorscaleValidator
3 from ._core import apply_default_cascade
4 import numpy as np  # is it fine to depend on np here?
5 
6 _float_types = []
7 
8 # Adapted from skimage.util.dtype
9 _integer_types = (
10     np.byte,
11     np.ubyte,  # 8 bits
12     np.short,
13     np.ushort,  # 16 bits
14     np.intc,
15     np.uintc,  # 16 or 32 or 64 bits
16     np.int_,
17     np.uint,  # 32 or 64 bits
18     np.longlong,
19     np.ulonglong,
20 )  # 64 bits
21 _integer_ranges = {t: (np.iinfo(t).min, np.iinfo(t).max) for t in _integer_types}
22 
23 
24 def _vectorize_zvalue(z):
25     if z is None:
26         return z
27     elif np.isscalar(z):
28         return [z] * 3 + [1]
29     elif len(z) == 1:
30         return list(z) * 3 + [1]
31     elif len(z) == 3:
32         return list(z) + [1]
33     elif len(z) == 4:
34         return z
35     else:
36         raise ValueError(
37             "zmax can be a scalar, or an iterable of length 1, 3 or 4. "
38             "A value of %s was passed for zmax." % str(z)
39         )
40 
41 
42 def _infer_zmax_from_type(img):
43     dt = img.dtype.type
44     rtol = 1.05
45     if dt in _integer_types:
46         return _integer_ranges[dt][1]
47     else:
48         im_max = img[np.isfinite(img)].max()
49         if im_max <= 1 * rtol:
50             return 1
51         elif im_max <= 255 * rtol:
52             return 255
53         elif im_max <= 65535 * rtol:
54             return 65535
55         else:
56             return 2 ** 32
57 
58 
59 def imshow(
60     img,
61     zmin=None,
62     zmax=None,
63     origin=None,
64     color_continuous_scale=None,
65     color_continuous_midpoint=None,
66     range_color=None,
67     title=None,
68     template=None,
69     width=None,
70     height=None,
71 ):
72     """
73     Display an image, i.e. data on a 2D regular raster.
74 
75     Parameters
76     ----------
77 
78     img: array-like image
79         The image data. Supported array shapes are
80 
81         - (M, N): an image with scalar data. The data is visualized
82           using a colormap.
83         - (M, N, 3): an image with RGB values.
84         - (M, N, 4): an image with RGBA values, i.e. including transparency.
85 
86     zmin, zmax : scalar or iterable, optional
87         zmin and zmax define the scalar range that the colormap covers. By default,
88         zmin and zmax correspond to the min and max values of the datatype for integer
89         datatypes (ie [0-255] for uint8 images, [0, 65535] for uint16 images, etc.). For
90         a multichannel image of floats, the max of the image is computed and zmax is the
91         smallest power of 256 (1, 255, 65535) greater than this max value,
92         with a 5% tolerance. For a single-channel image, the max of the image is used.
93 
94     origin : str, 'upper' or 'lower' (default 'upper')
95         position of the [0, 0] pixel of the image array, in the upper left or lower left
96         corner. The convention 'upper' is typically used for matrices and images.
97 
98     color_continuous_scale : str or list of str
99         colormap used to map scalar data to colors (for a 2D image). This parameter is
100         not used for RGB or RGBA images. If a string is provided, it should be the name
101         of a known color scale, and if a list is provided, it should be a list of CSS-
102         compatible colors.
103 
104     color_continuous_midpoint : number
105         If set, computes the bounds of the continuous color scale to have the desired
106         midpoint.
107 
108     range_color : list of two numbers
109         If provided, overrides auto-scaling on the continuous color scale, including
110         overriding `color_continuous_midpoint`.
111 
112     title : str
113         The figure title.
114 
115     template : str or dict or plotly.graph_objects.layout.Template instance
116         The figure template name or definition.
117 
118     width : number
119         The figure width in pixels.
120 
121     height: number
122         The figure height in pixels, defaults to 600.
123 
124     Returns
125     -------
126     fig : graph_objects.Figure containing the displayed image
127 
128     See also
129     --------
130 
131     plotly.graph_objects.Image : image trace
132     plotly.graph_objects.Heatmap : heatmap trace
133 
134     Notes
135     -----
136 
137     In order to update and customize the returned figure, use
138     `go.Figure.update_traces` or `go.Figure.update_layout`.
139     """
140     args = locals()
141     apply_default_cascade(args)
142 
143     img = np.asanyarray(img)
144     # Cast bools to uint8 (also one byte)
145     if img.dtype == np.bool:
146         img = 255 * img.astype(np.uint8)
147 
148     # For 2d data, use Heatmap trace
149     if img.ndim == 2:
150         trace = go.Heatmap(z=img, zmin=zmin, zmax=zmax, coloraxis="coloraxis1")
151         autorange = True if origin == "lower" else "reversed"
152         layout = dict(
153             xaxis=dict(scaleanchor="y", constrain="domain"),
154             yaxis=dict(autorange=autorange, constrain="domain"),
155         )
156         colorscale_validator = ColorscaleValidator("colorscale", "imshow")
157         range_color = range_color or [None, None]
158         layout["coloraxis1"] = dict(
159             colorscale=colorscale_validator.validate_coerce(
160                 args["color_continuous_scale"]
161             ),
162             cmid=color_continuous_midpoint,
163             cmin=range_color[0],
164             cmax=range_color[1],
165         )
166 
167     # For 2D+RGB data, use Image trace
168     elif img.ndim == 3 and img.shape[-1] in [3, 4]:
169         if zmax is None and img.dtype is not np.uint8:
170             zmax = _infer_zmax_from_type(img)
171         zmin, zmax = _vectorize_zvalue(zmin), _vectorize_zvalue(zmax)
172         trace = go.Image(z=img, zmin=zmin, zmax=zmax)
173         layout = {}
174         if origin == "lower":
175             layout["yaxis"] = dict(autorange=True)
176     else:
177         raise ValueError(
178             "px.imshow only accepts 2D single-channel, RGB or RGBA images. "
179             "An image of shape %s was provided" % str(img.shape)
180         )
181 
182     layout_patch = dict()
183     for v in ["title", "height", "width"]:
184         if args[v]:
185             layout_patch[v] = args[v]
186     if "title" not in layout_patch and args["template"].layout.margin.t is None:
187         layout_patch["margin"] = {"t": 60}
188     fig = go.Figure(data=trace, layout=layout)
189     fig.update_layout(layout_patch)
190     fig.update_layout(template=args["template"], overwrite=True)
191     return fig
192
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/packages/python/plotly/plotly/express/_imshow.py b/packages/python/plotly/plotly/express/_imshow.py
--- a/packages/python/plotly/plotly/express/_imshow.py
+++ b/packages/python/plotly/plotly/express/_imshow.py
@@ -1,7 +1,7 @@
 import plotly.graph_objs as go
 from _plotly_utils.basevalidators import ColorscaleValidator
 from ._core import apply_default_cascade
-import numpy as np  # is it fine to depend on np here?
+import numpy as np
 
 _float_types = []
 
@@ -107,7 +107,8 @@
 
     range_color : list of two numbers
         If provided, overrides auto-scaling on the continuous color scale, including
-        overriding `color_continuous_midpoint`.
+        overriding `color_continuous_midpoint`. Also overrides zmin and zmax. Used only
+        for single-channel images.
 
     title : str
         The figure title.
@@ -147,14 +148,18 @@
 
     # For 2d data, use Heatmap trace
     if img.ndim == 2:
-        trace = go.Heatmap(z=img, zmin=zmin, zmax=zmax, coloraxis="coloraxis1")
+        trace = go.Heatmap(z=img, coloraxis="coloraxis1")
         autorange = True if origin == "lower" else "reversed"
         layout = dict(
             xaxis=dict(scaleanchor="y", constrain="domain"),
             yaxis=dict(autorange=autorange, constrain="domain"),
         )
         colorscale_validator = ColorscaleValidator("colorscale", "imshow")
-        range_color = range_color or [None, None]
+        if zmin is not None and zmax is None:
+            zmax = img.max()
+        if zmax is not None and zmin is None:
+            zmin = img.min()
+        range_color = range_color or [zmin, zmax]
         layout["coloraxis1"] = dict(
             colorscale=colorscale_validator.validate_coerce(
                 args["color_continuous_scale"]

{"golden_diff": "diff --git a/packages/python/plotly/plotly/express/_imshow.py b/packages/python/plotly/plotly/express/_imshow.py\n--- a/packages/python/plotly/plotly/express/_imshow.py\n+++ b/packages/python/plotly/plotly/express/_imshow.py\n@@ -1,7 +1,7 @@\n import plotly.graph_objs as go\n from _plotly_utils.basevalidators import ColorscaleValidator\n from ._core import apply_default_cascade\n-import numpy as np  # is it fine to depend on np here?\n+import numpy as np\n \n _float_types = []\n \n@@ -107,7 +107,8 @@\n \n     range_color : list of two numbers\n         If provided, overrides auto-scaling on the continuous color scale, including\n-        overriding `color_continuous_midpoint`.\n+        overriding `color_continuous_midpoint`. Also overrides zmin and zmax. Used only\n+        for single-channel images.\n \n     title : str\n         The figure title.\n@@ -147,14 +148,18 @@\n \n     # For 2d data, use Heatmap trace\n     if img.ndim == 2:\n-        trace = go.Heatmap(z=img, zmin=zmin, zmax=zmax, coloraxis=\"coloraxis1\")\n+        trace = go.Heatmap(z=img, coloraxis=\"coloraxis1\")\n         autorange = True if origin == \"lower\" else \"reversed\"\n         layout = dict(\n             xaxis=dict(scaleanchor=\"y\", constrain=\"domain\"),\n             yaxis=dict(autorange=autorange, constrain=\"domain\"),\n         )\n         colorscale_validator = ColorscaleValidator(\"colorscale\", \"imshow\")\n-        range_color = range_color or [None, None]\n+        if zmin is not None and zmax is None:\n+            zmax = img.max()\n+        if zmax is not None and zmin is None:\n+            zmin = img.min()\n+        range_color = range_color or [zmin, zmax]\n         layout[\"coloraxis1\"] = dict(\n             colorscale=colorscale_validator.validate_coerce(\n                 args[\"color_continuous_scale\"]\n", "issue": "[BUG] zmin and zmax not working in imshow for 2d data\nSee for example\r\n```\r\nimport plotly.express as px\r\nimport numpy as np\r\nimg = np.random.random((10, 10))\r\npx.imshow(img, zmin=0.3, zmax=0.7)\r\n```\r\nI think this is because the Heatmap trace uses instead the `range_color` argument which was quite introduced quite late in the process. It's easy to fix, we just have to decide first if the API is ok as it is. \n", "before_files": [{"content": "import plotly.graph_objs as go\nfrom _plotly_utils.basevalidators import ColorscaleValidator\nfrom ._core import apply_default_cascade\nimport numpy as np  # is it fine to depend on np here?\n\n_float_types = []\n\n# Adapted from skimage.util.dtype\n_integer_types = (\n    np.byte,\n    np.ubyte,  # 8 bits\n    np.short,\n    np.ushort,  # 16 bits\n    np.intc,\n    np.uintc,  # 16 or 32 or 64 bits\n    np.int_,\n    np.uint,  # 32 or 64 bits\n    np.longlong,\n    np.ulonglong,\n)  # 64 bits\n_integer_ranges = {t: (np.iinfo(t).min, np.iinfo(t).max) for t in _integer_types}\n\n\ndef _vectorize_zvalue(z):\n    if z is None:\n        return z\n    elif np.isscalar(z):\n        return [z] * 3 + [1]\n    elif len(z) == 1:\n        return list(z) * 3 + [1]\n    elif len(z) == 3:\n        return list(z) + [1]\n    elif len(z) == 4:\n        return z\n    else:\n        raise ValueError(\n            \"zmax can be a scalar, or an iterable of length 1, 3 or 4. \"\n            \"A value of %s was passed for zmax.\" % str(z)\n        )\n\n\ndef _infer_zmax_from_type(img):\n    dt = img.dtype.type\n    rtol = 1.05\n    if dt in _integer_types:\n        return _integer_ranges[dt][1]\n    else:\n        im_max = img[np.isfinite(img)].max()\n        if im_max <= 1 * rtol:\n            return 1\n        elif im_max <= 255 * rtol:\n            return 255\n        elif im_max <= 65535 * rtol:\n            return 65535\n        else:\n            return 2 ** 32\n\n\ndef imshow(\n    img,\n    zmin=None,\n    zmax=None,\n    origin=None,\n    color_continuous_scale=None,\n    color_continuous_midpoint=None,\n    range_color=None,\n    title=None,\n    template=None,\n    width=None,\n    height=None,\n):\n    \"\"\"\n    Display an image, i.e. data on a 2D regular raster.\n\n    Parameters\n    ----------\n\n    img: array-like image\n        The image data. Supported array shapes are\n\n        - (M, N): an image with scalar data. The data is visualized\n          using a colormap.\n        - (M, N, 3): an image with RGB values.\n        - (M, N, 4): an image with RGBA values, i.e. including transparency.\n\n    zmin, zmax : scalar or iterable, optional\n        zmin and zmax define the scalar range that the colormap covers. By default,\n        zmin and zmax correspond to the min and max values of the datatype for integer\n        datatypes (ie [0-255] for uint8 images, [0, 65535] for uint16 images, etc.). For\n        a multichannel image of floats, the max of the image is computed and zmax is the\n        smallest power of 256 (1, 255, 65535) greater than this max value,\n        with a 5% tolerance. For a single-channel image, the max of the image is used.\n\n    origin : str, 'upper' or 'lower' (default 'upper')\n        position of the [0, 0] pixel of the image array, in the upper left or lower left\n        corner. The convention 'upper' is typically used for matrices and images.\n\n    color_continuous_scale : str or list of str\n        colormap used to map scalar data to colors (for a 2D image). This parameter is\n        not used for RGB or RGBA images. If a string is provided, it should be the name\n        of a known color scale, and if a list is provided, it should be a list of CSS-\n        compatible colors.\n\n    color_continuous_midpoint : number\n        If set, computes the bounds of the continuous color scale to have the desired\n        midpoint.\n\n    range_color : list of two numbers\n        If provided, overrides auto-scaling on the continuous color scale, including\n        overriding `color_continuous_midpoint`.\n\n    title : str\n        The figure title.\n\n    template : str or dict or plotly.graph_objects.layout.Template instance\n        The figure template name or definition.\n\n    width : number\n        The figure width in pixels.\n\n    height: number\n        The figure height in pixels, defaults to 600.\n\n    Returns\n    -------\n    fig : graph_objects.Figure containing the displayed image\n\n    See also\n    --------\n\n    plotly.graph_objects.Image : image trace\n    plotly.graph_objects.Heatmap : heatmap trace\n\n    Notes\n    -----\n\n    In order to update and customize the returned figure, use\n    `go.Figure.update_traces` or `go.Figure.update_layout`.\n    \"\"\"\n    args = locals()\n    apply_default_cascade(args)\n\n    img = np.asanyarray(img)\n    # Cast bools to uint8 (also one byte)\n    if img.dtype == np.bool:\n        img = 255 * img.astype(np.uint8)\n\n    # For 2d data, use Heatmap trace\n    if img.ndim == 2:\n        trace = go.Heatmap(z=img, zmin=zmin, zmax=zmax, coloraxis=\"coloraxis1\")\n        autorange = True if origin == \"lower\" else \"reversed\"\n        layout = dict(\n            xaxis=dict(scaleanchor=\"y\", constrain=\"domain\"),\n            yaxis=dict(autorange=autorange, constrain=\"domain\"),\n        )\n        colorscale_validator = ColorscaleValidator(\"colorscale\", \"imshow\")\n        range_color = range_color or [None, None]\n        layout[\"coloraxis1\"] = dict(\n            colorscale=colorscale_validator.validate_coerce(\n                args[\"color_continuous_scale\"]\n            ),\n            cmid=color_continuous_midpoint,\n            cmin=range_color[0],\n            cmax=range_color[1],\n        )\n\n    # For 2D+RGB data, use Image trace\n    elif img.ndim == 3 and img.shape[-1] in [3, 4]:\n        if zmax is None and img.dtype is not np.uint8:\n            zmax = _infer_zmax_from_type(img)\n        zmin, zmax = _vectorize_zvalue(zmin), _vectorize_zvalue(zmax)\n        trace = go.Image(z=img, zmin=zmin, zmax=zmax)\n        layout = {}\n        if origin == \"lower\":\n            layout[\"yaxis\"] = dict(autorange=True)\n    else:\n        raise ValueError(\n            \"px.imshow only accepts 2D single-channel, RGB or RGBA images. \"\n            \"An image of shape %s was provided\" % str(img.shape)\n        )\n\n    layout_patch = dict()\n    for v in [\"title\", \"height\", \"width\"]:\n        if args[v]:\n            layout_patch[v] = args[v]\n    if \"title\" not in layout_patch and args[\"template\"].layout.margin.t is None:\n        layout_patch[\"margin\"] = {\"t\": 60}\n    fig = go.Figure(data=trace, layout=layout)\n    fig.update_layout(layout_patch)\n    fig.update_layout(template=args[\"template\"], overwrite=True)\n    return fig\n", "path": "packages/python/plotly/plotly/express/_imshow.py"}], "after_files": [{"content": "import plotly.graph_objs as go\nfrom _plotly_utils.basevalidators import ColorscaleValidator\nfrom ._core import apply_default_cascade\nimport numpy as np\n\n_float_types = []\n\n# Adapted from skimage.util.dtype\n_integer_types = (\n    np.byte,\n    np.ubyte,  # 8 bits\n    np.short,\n    np.ushort,  # 16 bits\n    np.intc,\n    np.uintc,  # 16 or 32 or 64 bits\n    np.int_,\n    np.uint,  # 32 or 64 bits\n    np.longlong,\n    np.ulonglong,\n)  # 64 bits\n_integer_ranges = {t: (np.iinfo(t).min, np.iinfo(t).max) for t in _integer_types}\n\n\ndef _vectorize_zvalue(z):\n    if z is None:\n        return z\n    elif np.isscalar(z):\n        return [z] * 3 + [1]\n    elif len(z) == 1:\n        return list(z) * 3 + [1]\n    elif len(z) == 3:\n        return list(z) + [1]\n    elif len(z) == 4:\n        return z\n    else:\n        raise ValueError(\n            \"zmax can be a scalar, or an iterable of length 1, 3 or 4. \"\n            \"A value of %s was passed for zmax.\" % str(z)\n        )\n\n\ndef _infer_zmax_from_type(img):\n    dt = img.dtype.type\n    rtol = 1.05\n    if dt in _integer_types:\n        return _integer_ranges[dt][1]\n    else:\n        im_max = img[np.isfinite(img)].max()\n        if im_max <= 1 * rtol:\n            return 1\n        elif im_max <= 255 * rtol:\n            return 255\n        elif im_max <= 65535 * rtol:\n            return 65535\n        else:\n            return 2 ** 32\n\n\ndef imshow(\n    img,\n    zmin=None,\n    zmax=None,\n    origin=None,\n    color_continuous_scale=None,\n    color_continuous_midpoint=None,\n    range_color=None,\n    title=None,\n    template=None,\n    width=None,\n    height=None,\n):\n    \"\"\"\n    Display an image, i.e. data on a 2D regular raster.\n\n    Parameters\n    ----------\n\n    img: array-like image\n        The image data. Supported array shapes are\n\n        - (M, N): an image with scalar data. The data is visualized\n          using a colormap.\n        - (M, N, 3): an image with RGB values.\n        - (M, N, 4): an image with RGBA values, i.e. including transparency.\n\n    zmin, zmax : scalar or iterable, optional\n        zmin and zmax define the scalar range that the colormap covers. By default,\n        zmin and zmax correspond to the min and max values of the datatype for integer\n        datatypes (ie [0-255] for uint8 images, [0, 65535] for uint16 images, etc.). For\n        a multichannel image of floats, the max of the image is computed and zmax is the\n        smallest power of 256 (1, 255, 65535) greater than this max value,\n        with a 5% tolerance. For a single-channel image, the max of the image is used.\n\n    origin : str, 'upper' or 'lower' (default 'upper')\n        position of the [0, 0] pixel of the image array, in the upper left or lower left\n        corner. The convention 'upper' is typically used for matrices and images.\n\n    color_continuous_scale : str or list of str\n        colormap used to map scalar data to colors (for a 2D image). This parameter is\n        not used for RGB or RGBA images. If a string is provided, it should be the name\n        of a known color scale, and if a list is provided, it should be a list of CSS-\n        compatible colors.\n\n    color_continuous_midpoint : number\n        If set, computes the bounds of the continuous color scale to have the desired\n        midpoint.\n\n    range_color : list of two numbers\n        If provided, overrides auto-scaling on the continuous color scale, including\n        overriding `color_continuous_midpoint`. Also overrides zmin and zmax. Used only\n        for single-channel images.\n\n    title : str\n        The figure title.\n\n    template : str or dict or plotly.graph_objects.layout.Template instance\n        The figure template name or definition.\n\n    width : number\n        The figure width in pixels.\n\n    height: number\n        The figure height in pixels, defaults to 600.\n\n    Returns\n    -------\n    fig : graph_objects.Figure containing the displayed image\n\n    See also\n    --------\n\n    plotly.graph_objects.Image : image trace\n    plotly.graph_objects.Heatmap : heatmap trace\n\n    Notes\n    -----\n\n    In order to update and customize the returned figure, use\n    `go.Figure.update_traces` or `go.Figure.update_layout`.\n    \"\"\"\n    args = locals()\n    apply_default_cascade(args)\n\n    img = np.asanyarray(img)\n    # Cast bools to uint8 (also one byte)\n    if img.dtype == np.bool:\n        img = 255 * img.astype(np.uint8)\n\n    # For 2d data, use Heatmap trace\n    if img.ndim == 2:\n        trace = go.Heatmap(z=img, coloraxis=\"coloraxis1\")\n        autorange = True if origin == \"lower\" else \"reversed\"\n        layout = dict(\n            xaxis=dict(scaleanchor=\"y\", constrain=\"domain\"),\n            yaxis=dict(autorange=autorange, constrain=\"domain\"),\n        )\n        colorscale_validator = ColorscaleValidator(\"colorscale\", \"imshow\")\n        if zmin is not None and zmax is None:\n            zmax = img.max()\n        if zmax is not None and zmin is None:\n            zmin = img.min()\n        range_color = range_color or [zmin, zmax]\n        layout[\"coloraxis1\"] = dict(\n            colorscale=colorscale_validator.validate_coerce(\n                args[\"color_continuous_scale\"]\n            ),\n            cmid=color_continuous_midpoint,\n            cmin=range_color[0],\n            cmax=range_color[1],\n        )\n\n    # For 2D+RGB data, use Image trace\n    elif img.ndim == 3 and img.shape[-1] in [3, 4]:\n        if zmax is None and img.dtype is not np.uint8:\n            zmax = _infer_zmax_from_type(img)\n        zmin, zmax = _vectorize_zvalue(zmin), _vectorize_zvalue(zmax)\n        trace = go.Image(z=img, zmin=zmin, zmax=zmax)\n        layout = {}\n        if origin == \"lower\":\n            layout[\"yaxis\"] = dict(autorange=True)\n    else:\n        raise ValueError(\n            \"px.imshow only accepts 2D single-channel, RGB or RGBA images. \"\n            \"An image of shape %s was provided\" % str(img.shape)\n        )\n\n    layout_patch = dict()\n    for v in [\"title\", \"height\", \"width\"]:\n        if args[v]:\n            layout_patch[v] = args[v]\n    if \"title\" not in layout_patch and args[\"template\"].layout.margin.t is None:\n        layout_patch[\"margin\"] = {\"t\": 60}\n    fig = go.Figure(data=trace, layout=layout)\n    fig.update_layout(layout_patch)\n    fig.update_layout(template=args[\"template\"], overwrite=True)\n    return fig\n", "path": "packages/python/plotly/plotly/express/_imshow.py"}]}