Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Doc] Add Show Image Marks With Selection/Show Local Images Examples #3219

Merged
merged 8 commits into from
Oct 16, 2023
101 changes: 101 additions & 0 deletions doc/user_guide/marks/image.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,104 @@ Scatter Plot with Image Marks
)

alt.Chart(source).mark_image(width=50, height=50).encode(x="x", y="y", url="img")

Show Image Marks with Selection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This example demonstrates how to display image marks with drag selection. We create two charts:
one with point marks and the other with image marks, applying the selection filter only to the latter.
By combining these two charts, we can achieve the desired result.

.. altair-plot::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the two examples in this code will be easier to understand if we show them one at a time like in #2278 (comment) and don't hide the code by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update as below
image
image

:hide-code:
:div_class: properties-example

import altair as alt
import pandas as pd

source = pd.DataFrame.from_records(
[{'a': 1, 'b': 1, 'image': 'https://altair-viz.github.io/_static/altair-logo-light.png'},
{'a': 2, 'b': 2, 'image': 'https://avatars.githubusercontent.com/u/11796929?s=200&v=4'},
{'a': 3, 'b': 3, 'image': ''}]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this empty image included?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to remove this... just for testing if point withot image can be shown correctly

)

brush = alt.selection_interval()
point = alt.Chart(source, width=200, height=200).mark_circle(size=100).encode(
x='a',
y='b',
).add_params(
brush
)

img = alt.Chart(source).mark_image(width=50, height=75).encode(
x='a',
y='b',
url='image'
).transform_filter(
brush
)

img_faceted = alt.Chart(source, width=50, height=75).mark_image().encode(
url='image'
).facet(
alt.Facet('image', title='', header=alt.Header(labelFontSize=0))
).transform_filter(
brush
)


two_layered_chart = point + img
faceted_chart = point | img_faceted

alt.hconcat(
two_layered_chart.properties(title="Two Layered Chart"),
faceted_chart.properties(title="Faceted Chart"),
).configure_title(
fontSize=10,
anchor='start'
)

In the layered chart, images may overlap one other, using the faceted chart instead can
avoid this issue.

If you're looking to learn how to create an image tooltip that displays an image when hovering over a point,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you include the Image Tooltip example directly on this page under its own heading and remove the gallery example? I think this is a natural place for it and we have so many different gallery examples that it is sometimes hard to find what we are looking for there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Image Tooltip section
image

please see :ref:`Image Tooltip <gallery_image_tooltip>`. However, if the images for the tooltip are stored as NumPy
arrays, please refer to :ref:`Displaying Numpy Images in Tooltips <numpy-tooltip-imgs>`.

Use Local Images as Image Marks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
We could also show local images using Base64 encoding, replace the image path below
and create your own plot.
ChiaLingWeng marked this conversation as resolved.
Show resolved Hide resolved

.. code-block::

import altair as alt
import pandas as pd
from IPython.display import Image
import base64, io, IPython
from PIL import Image as PILImage

# replace your image path here
# recommend use raw string for absolute path; i.e. r'C:\Users\...\img00.jpg'
images = ["./img00.jpg", "./img01.jpg", "./img02.jpg"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this image https://altair-viz.github.io/_static/altair-logo-light.png' might be available locally to the doc build, either as _static/altair-logo-light.png' or just altair-logo-light.png'. Could you try with those two paths and see if you can actually use it as a local image? Then we could run this example in the docs instead of only showing the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update! The relative path is "doc/_static/gray-square.png"
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done 🙌

imgCode = []


for imgPath in images:
image = PILImage.open(imgPath)
output = io.BytesIO()
# choose the right format
image.save(output, format='JPEG')
encoded_string = "data:image/jpeg;base64,"+base64.b64encode(output.getvalue()).decode()
imgCode.append(encoded_string)

x = [0.5, 1.5, 2.5]
y = [0.5, 1.5, 2.5]
source = pd.DataFrame({"x": x, "y": y, "img": imgCode})
alt.Chart(source).mark_image(
width=50,
height=50
).encode(
x='x',
y='y',
url='img'
)