Example - Plot Image
Table of Contents
1) Altair
altair
เป็น visualization library อีกตัวหนึ่งที่คล้ายกับ plotly.express
ซึ่งสามารถดูรายละเอียดการลงได้จากลิ้ง https://altair-viz.github.io/getting_started/installation.html ด้วยคำสั่ง
!pip install altair vega_datasets
ลองทำตามตัวอย่างจาก https://altair-viz.github.io/user_guide/marks.html#image-mark
import altair as alt
import pandas as pd
source = pd.DataFrame.from_records([
{"x": 0.5, "y": 0.5, "img": "https://vega.github.io/vega-datasets/data/ffox.png"},
{"x": 1.5, "y": 1.5, "img": "https://vega.github.io/vega-datasets/data/gimp.png"},
{"x": 2.5, "y": 2.5, "img": "https://vega.github.io/vega-datasets/data/7zip.png"}
])
alt.Chart(source).mark_image(
width=50,
height=50
).encode(
x='x',
y='y',
url='img'
)
โดยคำสั่งของ altair
มีการทำงานดังนี้
alt
เป็นการเรียก library altair (จากที่เราimport altair as alt
).Chart(source)
เป็นการระบุว่าเราจะพลอตกราฟจากชุดข้อมูลsource
.mark_image()
เป็นการระบุว่าเราจะพลอตกราฟด้วยลักษณะแบบimage
(สามารถดูลักษณะทั้งหมดได้ที่ https://altair-viz.github.io/user_guide/marks.html).encode(x='x', y='y', url='img')
เป็นการระบุคอลัมน์ข้อมูลที่ใช้ในการพลอตกราฟแต่ละส่วน
โดยสามารถดูตาราง source
ที่สร้างขึ้นมาได้
source
x | y | img | |
---|---|---|---|
0 | 0.5 | 0.5 | https://vega.github.io/vega-datasets/data/ffox... |
1 | 1.5 | 1.5 | https://vega.github.io/vega-datasets/data/gimp... |
2 | 2.5 | 2.5 | https://vega.github.io/vega-datasets/data/7zip... |
2) Plotly Express
หากต้องการจะปรับขนาดของรูปภาพในกราฟด้วยจำเป็นจะต้องใช้ plotly
แทน
import plotly.express as px
ลองพลอตแบบ scatter
ด้วยข้อมูล source
ก่อน
fig = px.scatter(source, x="x", y="y")
fig
จากตัวอย่างการใส่รูปลงในกราฟ https://stackoverflow.com/questions/69680720/plotly-replace-x-label-with-image
เลยลองปรับโค้ดนิดหน่อยดู
fig = px.scatter(source, x="x", y="y")
for _, r in source.iterrows():
fig.add_layout_image(
source=Image.open(r["img"]),
x=r["x"],
y=r["y"],
xref="x",
yref="y",
xanchor="center",
sizex=1,
sizey=1,
)
fig
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-6-f078876a147b> in <module>
2 for _, r in source.iterrows():
3 fig.add_layout_image(
----> 4 source=Image.open(r["img"]),
5 x=r["x"],
6 y=r["y"],
NameError: name 'Image' is not defined
เจอ NameError
ว่า Image
ยังไม่ถูกกำหนด เพราะโค้ดตัวอย่างใช้ class Image
จาก PIL
from PIL import Image
fig = px.scatter(source, x="x", y="y")
for _, r in source.iterrows():
fig.add_layout_image(
source=Image.open(r["img"]),
x=r["x"],
y=r["y"],
xref="x",
yref="y",
xanchor="center",
sizex=1,
sizey=1,
)
fig
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-8-33e3bb4e2ead> in <module>
3 for _, r in source.iterrows():
4 fig.add_layout_image(
----> 5 source=Image.open(r["img"]),
6 x=r["x"],
7 y=r["y"],
/opt/conda/lib/python3.9/site-packages/PIL/Image.py in open(fp, mode, formats)
2910
2911 if filename:
-> 2912 fp = builtins.open(filename, "rb")
2913 exclusive_fp = True
2914
FileNotFoundError: [Errno 2] No such file or directory: 'https://vega.github.io/vega-datasets/data/ffox.png'
เจอ FileNotFoundError
บอกว่าไม่มีไฟล์ https://vega.github.io/vega-datasets/data/ffox.png
เพราะว่า Image
ไม่สามารถรับพารามิเตอร์เป็นลิ้งได้ จะต้องโหลดรูปมาไว้ในโฟลเดอร์เดียวกันก่อน
ซึ่งสามารถใช้คำสั่ง !wget
ได้ (เป็นคำสั่งสำหรับเครื่อง linux)
!wget https://vega.github.io/vega-datasets/data/ffox.png
!wget https://vega.github.io/vega-datasets/data/gimp.png
!wget https://vega.github.io/vega-datasets/data/7zip.png
--2022-07-22 05:50:33-- https://vega.github.io/vega-datasets/data/ffox.png
Resolving vega.github.io (vega.github.io)... 185.199.110.153, 185.199.109.153, 185.199.108.153, ...
Connecting to vega.github.io (vega.github.io)|185.199.110.153|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17628 (17K) [image/png]
Saving to: ‘ffox.png’
ffox.png 100%[===================>] 17.21K --.-KB/s in 0.002s
2022-07-22 05:50:33 (8.06 MB/s) - ‘ffox.png’ saved [17628/17628]
--2022-07-22 05:50:34-- https://vega.github.io/vega-datasets/data/gimp.png
Resolving vega.github.io (vega.github.io)... 185.199.109.153, 185.199.108.153, 185.199.110.153, ...
Connecting to vega.github.io (vega.github.io)|185.199.109.153|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8211 (8.0K) [image/png]
Saving to: ‘gimp.png’
gimp.png 100%[===================>] 8.02K --.-KB/s in 0s
2022-07-22 05:50:34 (39.1 MB/s) - ‘gimp.png’ saved [8211/8211]
--2022-07-22 05:50:34-- https://vega.github.io/vega-datasets/data/7zip.png
Resolving vega.github.io (vega.github.io)... 185.199.110.153, 185.199.111.153, 185.199.109.153, ...
Connecting to vega.github.io (vega.github.io)|185.199.110.153|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3969 (3.9K) [image/png]
Saving to: ‘7zip.png’
7zip.png 100%[===================>] 3.88K --.-KB/s in 0s
2022-07-22 05:50:35 (21.4 MB/s) - ‘7zip.png’ saved [3969/3969]
หลังจากได้ไฟล์ทั้งสามไฟล์แล้ว จำเป็นต้องแปลงตารางเพื่อให้มีชื่อไฟล์สำหรับการเรียกใช้แทนลิ้งด้วย
source = pd.DataFrame.from_records([
{"x": 0.5, "y": 0.5, "filename": "ffox.png"},
{"x": 1.5, "y": 1.5, "filename": "gimp.png"},
{"x": 2.5, "y": 2.5, "filename": "7zip.png"}
])
source
x | y | filename | |
---|---|---|---|
0 | 0.5 | 0.5 | ffox.png |
1 | 1.5 | 1.5 | gimp.png |
2 | 2.5 | 2.5 | 7zip.png |
fig = px.scatter(source, x="x", y="y")
for _, r in source.iterrows():
fig.add_layout_image(
source=Image.open(r["filename"]),
x=r["x"],
y=r["y"],
xref="x",
yref="y",
xanchor="center",
sizex=1,
sizey=1,
)
fig
ได้รูปตามที่ต้องการ ต่อไปจะทำให้รูปอยู่ตรงกลางจากที่สังเกตพารามิเตอร์ xanchor
แล้วลองหา yanchor
เพิ่ม
fig = px.scatter(source, x="x", y="y")
for _, r in source.iterrows():
fig.add_layout_image(
source=Image.open(r["filename"]),
x=r["x"],
y=r["y"],
xref="x",
yref="y",
xanchor="center",
yanchor="middle",
sizex=1,
sizey=1,
)
fig
ต่อไปอยากปรับขนาดของรูปภาพ โดยสังเกตว่ามีพารามิเตอร์ sizex
และ sizey
ซึ่งกำหนดว่าเป็น 1
โดยจะกำหนดขนาดของแต่ละรูปลงไปในตารางตั้งแต่แรกด้วย
source = pd.DataFrame.from_records([
{"x": 0.5, "y": 0.5, "filename": "ffox.png", "sz": 0.25},
{"x": 1.5, "y": 1.5, "filename": "gimp.png", "sz": 1},
{"x": 2.5, "y": 2.5, "filename": "7zip.png", "sz": 0.5}
])
source
x | y | filename | sz | |
---|---|---|---|---|
0 | 0.5 | 0.5 | ffox.png | 0.25 |
1 | 1.5 | 1.5 | gimp.png | 1.00 |
2 | 2.5 | 2.5 | 7zip.png | 0.50 |
fig = px.scatter(source, x="x", y="y")
for _, r in source.iterrows():
fig.add_layout_image(
source=Image.open(r["filename"]),
x=r["x"],
y=r["y"],
xref="x",
yref="y",
xanchor="center",
yanchor="middle",
sizex=r["sz"],
sizey=r["sz"],
)
fig