我一直试图找到一种在python图上显示图像的方法,图像对应于鼠标点击的位置。 这是我要去的地方: Annotated plot (needs an image instead of text)
我可以得到代码来显示颜色栏上的值,具体取决于我点击的多边形(这些是从普通的plt.scatter构建的,所以任何适用于散点的东西都适用于此)。 每个多边形都有一个我想要显示的相应图像而不是颜色值。
任何人都有任何线索如何做到这一点?
我目前正在使用mpldatacursor来显示注释,但如果另一个包更好,请告诉我!
祝福,非常感谢,
汤姆
这是代码(其中大部分都不是必需的,因为它包括多边形的绘图)。对于糟糕的代码道歉,我是新手
import numpy as np
import matplotlib.pyplot as plt
import mpldatacursor
import matplotlib.image as mpimg
import sys
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Voronoi, voronoi_plot_2d
import pandas as pd
import matplotlib.cm as cm
import matplotlib as mpl
import seaborn as sns
def voronoi_finite_polygons_2d(vor, radius=None):
"""
Reconstruct infinite voronoi regions in a 2D diagram to finite
regions.
Parameters
----------
vor : Voronoi
Input diagram
radius : float, optional
Distance to 'points at infinity'.
Returns
-------
regions : list of tuples
Indices of vertices in each revised Voronoi regions.
vertices : list of tuples
Coordinates for revised Voronoi vertices. Same as coordinates
of input vertices, with 'points at infinity' appended to the
end.
"""
if vor.points.shape[1] != 2:
raise ValueError("Requires 2D input")
new_regions = []
new_vertices = vor.vertices.tolist()
center = vor.points.mean(axis=0)
if radius is None:
radius = vor.points.ptp().max()*2
# Construct a map containing all ridges for a given point
all_ridges = {}
for (p1, p2), (v1, v2) in zip(vor.ridge_points, vor.ridge_vertices):
all_ridges.setdefault(p1, []).append((p2, v1, v2))
all_ridges.setdefault(p2, []).append((p1, v1, v2))
# Reconstruct infinite regions
for p1, region in enumerate(vor.point_region):
vertices = vor.regions[region]
if all(v >= 0 for v in vertices):
# finite region
new_regions.append(vertices)
continue
# reconstruct a non-finite region
ridges = all_ridges[p1]
new_region = [v for v in vertices if v >= 0]
for p2, v1, v2 in ridges:
if v2 < 0:
v1, v2 = v2, v1
if v1 >= 0:
# finite ridge: already in the region
continue
# Compute the missing endpoint of an infinite ridge
t = vor.points[p2] - vor.points[p1] # tangent
t /= np.linalg.norm(t)
n = np.array([-t[1], t[0]]) # normal
midpoint = vor.points[[p1, p2]].mean(axis=0)
direction = np.sign(np.dot(midpoint - center, n)) * n
far_point = vor.vertices[v2] + direction * radius
new_region.append(len(new_vertices))
new_vertices.append(far_point.tolist())
# sort region counterclockwise
vs = np.asarray([new_vertices[v] for v in new_region])
c = vs.mean(axis=0)
angles = np.arctan2(vs[:,1] - c[1], vs[:,0] - c[0])
new_region = np.array(new_region)[np.argsort(angles)]
# finish
new_regions.append(new_region.tolist())
return new_regions, np.asarray(new_vertices)
parameters = ['Age (Gyr)']#, 'Weighted metalicity M/H', 'Mass to light ratio', 'Total mass below -0.5 M/H', 'Fractional mass below -0.5 M/H']
all_info = [[0 for i in range(970)] for j in range(7)] # inititlise final array
all_info[0][:] = np.loadtxt('temp_matched.csv', usecols=(0),skiprows=0, delimiter=',')
all_info[1][:] = np.loadtxt('temp_matched.csv', usecols=(1),skiprows=0, delimiter=',')
all_info[2][:] = np.loadtxt('temp_matched.csv', usecols=(2),skiprows=0, delimiter=',')
all_info[3][:] = np.loadtxt('temp_matched.csv', usecols=(3),skiprows=0, delimiter=',')
all_info[4][:] = np.loadtxt('temp_matched.csv', usecols=(4),skiprows=0, delimiter=',')
mass_frac = np.loadtxt('weight_info.csv',skiprows=0)
contour_mass = np.loadtxt('tb.csv', usecols=(23),skiprows=1, delimiter=',')
contour_rad = np.loadtxt('tb.csv', usecols=(11),skiprows=1, delimiter=',')
z = np.loadtxt('tb.csv', usecols=(24),skiprows=1, delimiter=',')
#convert to kpc
contour_rad = contour_rad / 3600.0 #degrees
contour_rad = (contour_rad / 180.0) * 3.14159 #degrees to rads
q_0 = (0.3089 / 2) - 0.6911 #q_0 from q_0 = (\Omega_M / 2) - \Omega_Lambda
distance = ((2.99E8 * z) / 67740.0) * (1 + (z*(1-q_0))/(np.sqrt(1+(2*q_0) * z) + 1 + q_0 * z))
distance = distance * 1000.0 #distance (into kpc)
contour_rad = distance * np.tan(contour_rad) #radius from radians
contour_rad = np.log10(contour_rad) #to log (if needed for plotting point density)
true_mass = [0] * len(all_info[0][:])
for h in range(len(all_info[0][:])):
true_mass[h] = 10 ** all_info[0][h]
tot_frac_mass = true_mass * mass_frac
all_info[5][:] = tot_frac_mass[:]
all_info[6][:] = mass_frac # fractional mass
#do the actual voronoi stuff
allpoints = [all_info[0][:], all_info[1][:]]
points = np.swapaxes(allpoints,0,1)
vor = Voronoi(points) # voronoi calc
regions, vertices = voronoi_finite_polygons_2d(vor)
for item in range(len(parameters)):
plt.figure(item+1)
voronoi_plot_2d(vor, show_vertices = False, show_points = False, line_alpha = 0.5)
colour = all_info[item + 2][:]
minima = min(colour)
maxima = max(colour)
norm = mpl.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.plasma)
img=mpimg.imread('/home/tom/Documents/phd/diagonals/re8/added_spectra/plots/mass_frac/mass_fraction9.png')
count = 0
for region in regions:
polygon = vertices[region]
if ((colour[count] < maxima) & (colour[count] > minima)):
plt.fill(*zip(*polygon), color=mapper.to_rgba(colour[count]), zorder=1, label=colour[count])
count = count + 1
# plot
#for r in range(len(vor.point_region)):
# region = vor.regions[vor.point_region[r]]
# if not -1 in region:
# polygon = [vor.vertices[i] for i in region]
# plt.fill(*zip(*polygon), color=mapper.to_rgba(colour[r]), zorder=1)
#im = plt.scatter(all_info[0][:], all_info[1][:], c=all_info[item + 2][:], cmap=cm.plasma, alpha=1.0)
#use this line instead to limit colour according to vmin and vmax
im = plt.scatter(all_info[0][:], all_info[1][:], c=all_info[item + 2][:], cmap=cm.plasma, alpha=1.0, vmin=minima, vmax=maxima)
cb = plt.colorbar(im)
plt.ylabel('Radius log$_{10}$(Kpc)')
plt.xlabel('Mass: log$_{10}$(M$_{\odot}$)')
cb.set_label(label='%s' %(parameters[item]))
plt.title('Mass size: %s' %(parameters[item]))
plt.xlim(8.5, 11.5)
plt.ylim(-0.2, 1.2)
mpldatacursor.datacursor(formatter='{label}'.format)
#mpldatacursor.datacursor(formatter='{label}'.format)
plt.show()