fana さんが回答してくださった方法で実装してみました。
python
1 import matplotlib . pyplot as plt
2 from matplotlib . patches import Rectangle
3 import numpy as np
4
5 mat = np . array ( [ [ 3 , 4 , 6 , 9 , 0 , 8 ] ,
6 [ 2 , 8 , 5 , 0 , 3 , 5 ] ,
7 [ 4 , 8 , 1 , 0 , 3 , 1 ] ,
8 [ 0 , 4 , 3 , 7 , 1 , 2 ] ,
9 [ 4 , 2 , 6 , 1 , 0 , 9 ] ,
10 [ 7 , 2 , 1 , 6 , 2 , 8 ] ] , dtype = float )
11 angle = 10 # x 軸の回転角度 (degree)
12 radius = np . array ( mat . shape ) // 2 # 半径
13
14 def create_rotation_matrix ( angle ) :
15 t = np . deg2rad ( angle )
16 return np . array ( [ [ np . cos ( t ) , - np . sin ( t ) ] ,
17 [ np . sin ( t ) , np . cos ( t ) ] ] )
18 R = create_rotation_matrix ( - angle ) # x 軸の回転方向とは逆の方向に回転する回転行列
# 各セルの4点の座標を作成する。
cells = []
id_ = 0 # あとでどのセルが含まれているのか確認するための識別子 (デバッグ用)
for (i, j), value in np.ndenumerate(mat):
# セルの左下の点 (x, y) を定義する。
x, y = j - radius[1], radius[0] - i - 1
# セルを構成する4点を作成する。
rect = np.array([[x, y], [x + 1, y], [x + 1, y + 1], [x, y + 1], [x, y]])
# セルを構成する4点を回転させる。
rect = rect.dot(R.T)
cells.append((id_, rect, value))
id_ += 1
各区別 [x_i, x_{i + 1}] に含まれるセルを見つけて、その値の平均を計算する。
edges = np.arange(-radius[1], radius[1] + 1)
for left, right in zip(edges, edges[1:]):
values = []
for id_, rect, value in cells:
if np.any((left <= rect[:, 0]) & (rect[:, 0] <= right)):
values.append((id_, value)) # セルの4隅の1点でも [left, right] に含まれる場合
values = sorted(values, key=lambda x: x[0]) # 見やすいように id でソートする。
mean = np.mean([x[1] for x in values]) # 平均
print('{} <= x <= {}:\n value: {}\n mean: {}'.format(
left, right, values, mean))
-3 <= x <= -2:
value: [(0, 3.0), (6, 2.0), (12, 4.0), (18, 0.0), (19, 4.0), (24, 4.0), (25, 2.0), (30, 7.0), (31, 2.0)]
mean: 3.111111111111111
-2 <= x <= -1:
value: [(0, 3.0), (1, 4.0), (6, 2.0), (7, 8.0), (12, 4.0), (13, 8.0), (18, 0.0), (19, 4.0), (20, 3.0), (25, 2.0), (26, 6.0), (31, 2.0), (32, 1.0)]
mean: 3.6153846153846154
-1 <= x <= 0:
value: [(1, 4.0), (2, 6.0), (7, 8.0), (8, 5.0), (13, 8.0), (14, 1.0), (15, 0.0), (19, 4.0), (20, 3.0), (21, 7.0), (26, 6.0), (27, 1.0), (32, 1.0), (33, 6.0)]
mean: 4.285714285714286
0 <= x <= 1:
value: [(2, 6.0), (3, 9.0), (8, 5.0), (9, 0.0), (14, 1.0), (15, 0.0), (16, 3.0), (20, 3.0), (21, 7.0), (22, 1.0), (27, 1.0), (28, 0.0), (33, 6.0), (34, 2.0)]
mean: 3.142857142857143
1 <= x <= 2:
value: [(3, 9.0), (4, 0.0), (9, 0.0), (10, 3.0), (15, 0.0), (16, 3.0), (17, 1.0), (22, 1.0), (23, 2.0), (28, 0.0), (29, 9.0), (34, 2.0), (35, 8.0)]
mean: 2.923076923076923
2 <= x <= 3:
value: [(4, 0.0), (5, 8.0), (10, 3.0), (11, 5.0), (16, 3.0), (17, 1.0), (23, 2.0), (29, 9.0), (35, 8.0)]
mean: 4.333333333333333
python
1 # デバッグ用
2 ###################################################################
3 fig , ax = plt . subplots ( figsize = ( 6 , 6 ) )
4
5 # 各セルを描画する。
6 for id_ , rect , value in cells :
7 ax . plot ( rect [ : , 0 ] , rect [ : , 1 ] , c = 'gray' , alpha = 0.5 ) # セルの枠線
8 cx , cy = ( rect [ 0 ] + rect [ 2 ] ) / 2 # セルの中心
9 s = '{}:{}' . format ( id_ , value )
10 ax . text ( cx , cy , s , ha = 'center' , va = 'center' , rotation = - angle ) # 値
11 ax . autoscale ( False )
12 # x 軸、y 軸を引く。
13 ax . axhline ( ) , ax . axvline ( )
14 # 垂直線を引く
15 ax . vlines ( edges , * ax . get_xlim ( ) , alpha = 0.5 )