使用 Python 绘制散点数据并创建热图

问题描述 投票:0回答:1

我向消费者展示了一张图片,并要求他们点击他们最喜欢的一点。因此,我得到了该图像上的点击数据(x,y 格式,其中 x 从左到右,y 从下到上)。我正在尝试使用相同的方法创建热图并将其覆盖在原始图像上。

我的代码

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import imageio.v2 as imageio
import cv2
from scipy.ndimage import gaussian_filter

image_path = 'C:\\Users\\Anurag\\Desktop\\Heatmaps\\Original design\\Holi control_withPrice1.png'
image = imageio.imread(image_path)

clicks_file = 'C:\\Users\\Anurag\\Desktop\\Heatmaps\\clickfiles\\Study1_Q19_1stArea.csv'
clicks_data = pd.read_csv(clicks_file)

x = clicks_data['x'].values
y = clicks_data['y'].values

marker_size = 40
extent = [0, image.shape[1], 0, image.shape[0]]
plt.clf()
plt.scatter(x, y, c='red', s=marker_size,alpha=0.5,cmap='jet') 
plt.imshow(image, extent=extent, origin='upper', alpha=0.3)
plt.show()

heatmap, xedges, yedges = np.histogram2d(x,y,bins=(image.shape[1], image.shape[0]))
heatmap = gaussian_filter(heatmap, sigma=16)
extent = [0, image.shape[1], 0,image.shape[0]]  # Set extent to match image size

plt.clf()
plt.imshow(image, extent=extent, origin='upper', alpha=0.3)
plt.imshow(heatmap.T, extent=extent, origin='lower', alpha=.5,cmap='jet')
plt.show()

我得到的输出

我得到的散点图:

Scatter plot I am getting

我得到的热图:

Heatmap I am getting

我需要帮助解决的问题

  1. 如果您查看上面的散点图和热图,您会发现我的热图和散点图点看起来不同,并且不完全相同的位置。
  2. 热图强度低。我需要它看起来像下面这样(只是一个示例)。

图像叠加的预期结果:

expected result with image overlay

任何帮助将不胜感激。

python heatmap scatter-plot
1个回答
0
投票

下面的示例将 alpha 阴影密度图叠加到散点数据上,下方有图像。这是对原始代码的修改。

减少

bw_method=
将使密度图更加聚集,增加它将使密度图更加分散。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from PIL import Image

image_path = 'img.png'
image = np.array( Image.open(image_path) )

# 
# Create test data
#
# clicks_data = pd.read_csv(clicks_file)
from sklearn.datasets import make_blobs
X, _ = make_blobs(n_samples=300, centers=4, random_state=3)
X -= X.min(axis=0)
X = (X * 20).round().astype(int)
clicks_data = pd.DataFrame({'x': X[:, 0], 'y': X[:, 1]})

#
# Scatter data and render image
#
x = clicks_data['x'].values
y = clicks_data['y'].values

adjust_scale = 1 #adjust scale if required, respecting image proportions
extent = [0, x.max() * adjust_scale, 0, image.shape[0] / image.shape[1] * x.max() * adjust_scale]
plt.scatter(x, y, c='tab:brown', s=10, alpha=.8, edgecolor='none', marker='s')
plt.imshow(image, extent=extent, alpha=0.3, origin='upper')

#
#Fit a density estimator
#
from scipy.stats import gaussian_kde
density_estimator = gaussian_kde(dataset=clicks_data.values.T, bw_method=0.2)

#Get the density estimates over a fine grid
grid_resolution = 100
x_grid, y_grid = np.meshgrid(
    np.linspace(0, extent[1], num=grid_resolution),
    np.linspace(0, extent[3], num=grid_resolution)
)
grid_coords = np.column_stack([x_grid.ravel(), y_grid.ravel()])
density_map = density_estimator(grid_coords.T).T.reshape(x_grid.shape)

#Modify the cmap to have alpha shading from transparent to opaque
from matplotlib.colors import LinearSegmentedColormap

cmap_name = 'jet'
cmap_rgba = plt.get_cmap(cmap_name)(range(256))
cmap_rgba[:, -1] = np.linspace(0, 1, len(cmap_rgba))
cmap_alpha = LinearSegmentedColormap.from_list(name='', colors=cmap_rgba)

plt.imshow(
    density_map, extent=extent, interpolation='spline16',
    origin='lower', cmap=cmap_alpha
)

#Optional formatting
plt.gcf().set_size_inches(4, 4)
plt.gca().axis('off')
plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.