Skip to content

Pixel shift in render_images #216

Closed
Closed

Description

@quentinblampey

Hello,

When plotting an image, it seems that there is a 0.5-pixel shift. This is not visible for large images but becomes very visible if we zoom in, and, mostly, it gets amplified with transformations (a Scale(1000, 1000) transformation will create a shift of 500 pixels).

Minimum reproducible example

import numpy as np
import spatialdata_plot
import spatialdata
from spatialdata.models import Image2DModel
from spatial_image import SpatialImage

image = SpatialImage(np.zeros((1, 4, 8)), dims=("c", "y", "x"))
image = Image2DModel.parse(image)

sdata = spatialdata.SpatialData(images={"image": image})

sdata.pl.render_images().pl.show()

It should render this image (we see that the image is not reaching (8, 4), but (7.5, 3.5) instead):
image

Maybe I did something wrong with the x-coords or y-coords? Should we update the coords or they should be fine by default?

Sorry for such a minor issue...

Activity

  1. changed the title [-]pixel shift in `render_images`[/-] [+]Pixel shift of 0.5 in `render_images`[/+] on Feb 15, 2024
  2. changed the title [-]Pixel shift of 0.5 in `render_images`[/-] [+]Pixel shift in `render_images`[/+] on Feb 15, 2024
  3. LucaMarconato commented on Feb 19, 2024

    @LucaMarconato
    Member

    Thanks for reporting!

    Maybe related to this: scverse/spatialdata#165. Also, if fixed before, better to add a test so that we verify we don't reintroduce this after scverse/spatialdata#308 is closed.

  4. Sonja-Stockhaus commented on Oct 25, 2024

    @Sonja-Stockhaus
    Collaborator

    This is also problematic for the datashader backend, because if an image is rendered before, its limits are used to determine the canvas size => we see an offset of the datashader points compared to what matplotlib would give us (and what the axis labels say!)

    e.g.

    from spatialdata import SpatialData
    from spatialdata.models import Image2DModel, PointsModel
    from spatialdata.transformations import Identity
    import matplotlib.pyplot as plt
    
    sdata = SpatialData(
        images={
            "image1": Image2DModel.parse(
                np.full((10, 10, 3), fill_value=128), dims=("y", "x", "c")
            )
        },
        points={
            "points1": PointsModel.parse(
                pd.DataFrame({"y": [0.1, 0.1, 0.9, 0.9], "x": [0.1, 0.9, 0.9, 0.1]}),
                transformations={"global": Identity()},
            )
        },
    )
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
    sdata.pl.render_images().pl.render_points("points1", method="datashader", size=40, color="red").pl.show(ax=ax1, title="datashader")
    sdata.pl.render_images().pl.render_points("points1", method="matplotlib", color="red", size=2).pl.show(ax=ax2, title="matplotlib")

    gives me:
    Image

    @timtreis FYI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions