現状のデータとしては,三次元空間の等高線を縦にぶった切って得られた断面の高さ情報しか持ってないので,ここから等高線を描くとしたら,断面から三次元空間の物体を予測して描くしかないです.
代替案としては,plt.scatter()
を使って2Dで描くならカラーマップをz
で割り当てる,または3Dでそのまま散布図を描画する方法があります.
厳密に,x
とy
が周期的に一致して次のようになっていれば,np.meshgrid()
を適用したplt.contor()
が使えます.
Python
1import numpy as np
2from itertools import product
3from matplotlib import pyplot as plt
4
5def del_duplicates(x): # to ordered monotonically
6 return sorted(set(x), key = x.index)
7
8x = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] # x is not ordered by monotonically
9y = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
10z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
11
12dx, dy = map(del_duplicates, (x, y))
13X, Y = np.meshgrid(dx, dy)
14Z = np.zeros_like(X)
15
16for n, (i, j) in enumerate(product(range(len(dx)), range(len(dy)))):
17 Z[i, j] = z[n]
18
19print(Z)
20
21fig, ax = plt.subplots(1, 3)
22ax[0].scatter(x, y, c = z)
23ax[0].set_xlabel('x')
24ax[0].set_ylabel('y')
25ax[0].set_title('scatter')
26
27ax[1].tricontour(x, y, z)
28ax[1].set_xlabel('x')
29ax[1].set_ylabel('y')
30ax[1].set_title('tricontour')
31
32ax[2].contour(X, Y, Z)
33ax[2].set_xlabel('x')
34ax[2].set_ylabel('y')
35ax[2].set_title('contour')
36
37plt.show()
ただ,このような変換ができるということは当然plt.tricontour()
を使うこともできるということになりますね.
結果は次のようになります.
