{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## The `extent` parameter in `geom_imshow()` \n", "\n", "A list of four numbers: `[left, right, bottom, top]` that\n", "defines the image bounding box\n", "in terms of 'data coordinates'." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:29.354536Z", "iopub.status.busy": "2024-04-17T07:28:29.354415Z", "iopub.status.idle": "2024-04-17T07:28:29.672629Z", "shell.execute_reply": "2024-04-17T07:28:29.672374Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "from lets_plot import *\n", "\n", "LetsPlot.setup_html()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default `extent` is derived from the image's array dimentions: `[-0.5, ncol-0.5, -0.5, nrow-0.5]`.\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:29.685375Z", "iopub.status.busy": "2024-04-17T07:28:29.685243Z", "iopub.status.idle": "2024-04-17T07:28:29.717330Z", "shell.execute_reply": "2024-04-17T07:28:29.717077Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# An 2x2 pix image by default has extent [-0.5, 1.5, -0.5, 1.5]\n", "arr = np.array([\n", " [[150, 0, 0], [0, 150, 0]],\n", " [[0, 0, 150], [150, 150, 0]]\n", " ])\n", "\n", "ggplot() + geom_imshow(arr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## When does image `extent` need to be set explicitly\n", "\n", "Let's assume that our image doesn't exist in vacuum but is related to some data, \n", "and the image' bounding box in the 'data coordinates' is: \n", "\n", "- `(x, y) = (0, -1)`\n", "- `(width, height) = (8, 3)`.\n", "\n", "The image `extent` in this case would be: `[0, 8, -1, 3]`." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:29.718438Z", "iopub.status.busy": "2024-04-17T07:28:29.718349Z", "iopub.status.idle": "2024-04-17T07:28:29.720808Z", "shell.execute_reply": "2024-04-17T07:28:29.720583Z" } }, "outputs": [], "source": [ "# Generate demo data.\n", "np.random.seed(42)\n", "\n", "cov0=[[1, -.8], \n", " [-.8, 1]] \n", "cov1=[[ 10, .1],\n", " [.1, .1]]\n", "\n", "x0, y0 = np.random.multivariate_normal(mean=[4,0], cov=cov0, size=400).T\n", "x1, y1 = np.random.multivariate_normal(mean=[4,1], cov=cov1, size=400).T\n", "\n", "data = dict(\n", " x = np.concatenate((x0,x1)),\n", " y = np.concatenate((y0,y1))\n", ")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:29.721904Z", "iopub.status.busy": "2024-04-17T07:28:29.721765Z", "iopub.status.idle": "2024-04-17T07:28:29.829787Z", "shell.execute_reply": "2024-04-17T07:28:29.829429Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(data, aes('x', 'y')) + geom_density2d() + ggsize(620, 300)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's show the data and the image on the same plot." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:29.831178Z", "iopub.status.busy": "2024-04-17T07:28:29.830907Z", "iopub.status.idle": "2024-04-17T07:28:29.939678Z", "shell.execute_reply": "2024-04-17T07:28:29.939368Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(ggplot(data, aes('x', 'y')) + \n", " geom_imshow(arr, extent=[0, 8, -1, 3]) + \n", " geom_density2d(color=\"yellow\") + \n", " ggsize(620, 300) + \n", " flavor_high_contrast_dark())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# \n", "## Flipping and transposing image using `extent`" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:29.940903Z", "iopub.status.busy": "2024-04-17T07:28:29.940726Z", "iopub.status.idle": "2024-04-17T07:28:30.655179Z", "shell.execute_reply": "2024-04-17T07:28:30.654848Z" } }, "outputs": [ { "data": { "text/plain": [ "(225, 225, 3)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Load image file.\n", "from PIL import Image\n", "import requests\n", "from io import BytesIO\n", "\n", "response = requests.get('https://github.com/JetBrains/lets-plot-docs/raw/master/source/examples/cookbook/images/fisher_boat.png')\n", "\n", "image = Image.open(BytesIO(response.content))\n", "boat_arr = np.asarray(image)\n", "boat_arr.shape\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:30.656230Z", "iopub.status.busy": "2024-04-17T07:28:30.656122Z", "iopub.status.idle": "2024-04-17T07:28:30.669561Z", "shell.execute_reply": "2024-04-17T07:28:30.669178Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot() + geom_imshow(image_data=boat_arr)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:28:30.670691Z", "iopub.status.busy": "2024-04-17T07:28:30.670579Z", "iopub.status.idle": "2024-04-17T07:28:30.718272Z", "shell.execute_reply": "2024-04-17T07:28:30.718054Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dim = 100\n", "\n", "ext_base = [0, dim, 0, dim]\n", "ext_flip_x = [dim, 0, 0, dim]\n", "ext_flip_y = [0, dim, dim, 0]\n", "ext_transpose = [dim, 0, dim, 0]\n", "\n", "label_data = dict(\n", " x = [50, 150, 150, 50],\n", " y = [200, 200, 0, 0],\n", " label = [\"original\", \"flip columns\", \"flip rows\", \"transpose\"]\n", ")\n", "\n", "(ggplot() + \n", " geom_imshow(\n", " boat_arr, \n", " extent=[v + dim if i in (2, 3) else v for i, v in enumerate(ext_base)]\n", " ) + \n", " geom_imshow(\n", " boat_arr, \n", " extent=[v + dim for v in ext_flip_x]\n", " ) + \n", " geom_imshow(\n", " boat_arr, \n", " extent=[v + dim if i in (0, 1) else v for i, v in enumerate(ext_flip_y)]\n", " ) + \n", " geom_imshow(\n", " boat_arr, \n", " extent=ext_transpose\n", " ) + \n", " geom_hline(yintercept=100, color=\"yellow\", tooltips=\"none\") + \n", " geom_vline(xintercept=100, color=\"yellow\", tooltips=\"none\") + \n", " geom_label(aes(\"x\", \"y\", label=\"label\"), data=label_data) +\n", " ggsize(700, 700)\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 4 }