是否可以创建具有静态大小的RegularPolyCollection?
我想以数据单位给出大小,而不是以屏幕为单位。就像偏移一样。
目标是拥有1440个六边形像素,直径为9.5毫米的相机图像。
有可能通过循环超过1440个多边形来实现这一点,但是我没有成功创建具有巨大优势的PolyCollection,用于创建色彩映射等。
这是我用来绘制静态大小的1440六边形的代码:
for c, x, y in zip(pixel_color, pixel_x, pixel_y):
ax.add_artist(
RegularPolygon(
xy=(x, y),
numVertices=6,
radius=4.75,
orientation=0.,
facecolor=c,
edgecolor=edgecolor,
linewidth=1.5,
)
)
此代码生成相同但有错误而非静态(就数据而言)大小:
a = 1/np.sqrt(3) * 9.5
collection = RegularPolyCollection(
numsides=6,
rotation=0.,
sizes=np.ones(1440)*np.pi*a**2, # tarea of the surrounding circle
facecolors=pixel_colors,
edgecolors="g",
linewidth=np.ones(1440)*1.5,
offsets=np.transpose([pixel_x, pixel_y]),
transOffset=self.transData,
)
self.add_collection(collection)
如何通过集合的优势实现六边形的静态尺寸?
答案 0 :(得分:0)
我最近遇到了同样的问题。解决方案是简单地使用PatchCollection
而不是RegularPolyCollection
。但是,缺点是您必须手动实例化每个补丁。下面你会找到一个代码示例,它在常规网格上绘制10,000个正六边形。
# imports
import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon
from matplotlib.collections import PatchCollection
import numpy as np
# set up figure
fig, ax = plt.subplots(1)
# positions
pixel_x, pixel_y = np.indices((100, 100))
pixel_color = np.random.random_sample(30000).reshape(10000, 3)
dx = 4 # horizontal stride
dy = 5 # vertical stride
# set static radius
poly_radius = 2.5
# list to hold patches
patch_list = []
# creat the patches
for c, x, y in zip(pixel_color, pixel_x.flat, pixel_y.flat):
patch_list.append(
RegularPolygon(
xy=(x*dy, y*dy),
numVertices=6,
radius=poly_radius,
orientation=0.,
facecolor=c,
edgecolor='k'
)
)
pc = PatchCollection(patch_list, match_original=True)
ax.add_collection(pc)
ax.axis([-3, 480, -3, 480])
plt.show()
在我的机器上,此代码需要大约2.8秒才能呈现所有内容。
答案 1 :(得分:0)
如果您想使用RegularPolyCollection
,我已经弄清楚了如何正确设置尺寸。主要限制是尺寸取决于轴转换,因此在计算尺寸之前,必须将轴限制和图形尺寸锁定在 中。
在以下版本中,图形和轴也必须是正方形。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
sin60 = np.sin(np.pi/3)
fig, ax = plt.subplots()
fig.set_size_inches(8, 8)
ax.set_aspect(1)
ax.set_xlim(-1.5*sin60, +1.5*sin60)
ax.set_ylim(-1.5*sin60, +1.5*sin60)
ax.set_frame_on(False)
ax.set_xticks([])
ax.set_yticks([])
coords = [[-1/2, +sin60/2], [+1/2, +sin60/2], [0, -sin60/2]]
radius = .5/sin60
data_to_pixels = ax.transData.get_matrix()[0, 0]
pixels_to_points = 1/fig.get_dpi()*72.
size = np.pi*(data_to_pixels*pixels_to_points*radius)**2
hexes = mpl.collections.RegularPolyCollection(
numsides=6,
sizes=3*(size,),
offsets=coords,
edgecolors=3*('k',),
linewidths=1,
transOffset=ax.transData)
ax.add_collection(hexes)