簡體   English   中英

Python 中的 Plot 4D 數據熱圖

[英]Plot 4D data heatmap in Python

嘿,我怎樣才能 plot 3D 中的 2D 熱圖? 現在我創建一個 python 腳本來制作一個二維熱圖 Plot,其中的數據來自 CSV(CSV 格式:x,y,z,v)。 例如:

先csv

0,000;-110,000;110,000;0,101

第二 csv

0,000;-66,000;110,000;0,104

第三 csv

0,000;-22,000;110,000;0,119

……

在此示例中,它是 xz 平面中的熱圖,我創建了另外五個圖,以便我可以在 3D 房間中插入六個 xz 平面圖。 4D 熱圖中 plot 和 matplotlib有一個非常好的例子。 但我不知道如何在我的情況下使用它。

import numpy as np
import os
import matplotlib.pyplot as plt
from scipy.interpolate import griddata


'Create a list for every parameter'
x = []
y = []
z = []
v = []

file_path = "path/."

'Insert data from csv into lists'
for root, dirs, files in os.walk(file_path, topdown=False):
   for name in files:
       if name[-4:] != '.csv': continue
       with open(os.path.join(root, name)) as data:
          data = np.genfromtxt((line.replace(',', '.') for line in data), delimiter=";")
          if data[1] == 22: 
            x.append(data[0])
            y.append(data[1])
            z.append(data[2])
            v.append(data[3])

'Create axis data'
xi = np.linspace(min(x), max(x), 1000)
zi = np.linspace(min(z), max(z), 1000)
vi = griddata((x, z), v, (xi[None,:], zi[:,None]), method='cubic')

'Create the contour plot'
CS = plt.contourf(xi, zi, vi, 20, cmap=plt.cm.rainbow)
plt.title("Heatmap xz-plane", y=1.05, 
          fontweight="bold")
plt.xlabel("length x in cm")
plt.xticks(np.arange(0, 201, step=40))
plt.ylabel("height z in cm")
plt.yticks(np.arange(110, 251, step=20))
cbar = plt.colorbar()
cbar.set_label("velocity v in m/s", labelpad=10)
plt.savefig('testplot.png', dpi=400)  
plt.show()

滿足@keepAlive 的要求,希望看到他未經測試的答案的結果......:

它實際上很好用:-)

在此處輸入圖像描述

在此處輸入圖像描述

免責聲明:我是引用示例的作者,所以我認為復制/粘貼自己並不是真正的問題。

請注意,您的數據集看起來(至少)不是 3 維的。 但我會假設存在不情願的選擇偏差。

您首先需要匯總每個高度級別的“點”,我認為這是您的向量的第三個組成部分。 一旦聚集,它們將構成你的位面。

# libraries
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import scipy.interpolate as si
from matplotlib import cm
import collections as co  # <------------------
import pandas as pd
import numpy as np

planes = co.defaultdict(list)

for root, dirs, files in os.walk(file_path, topdown=False):
   # [...]
       # [...]
       # [...]
          # [...]
          # [...]
            level = data[2]  # <------ third component.
            planes[level].append(data)

現在,在那個階段,我們有一個 arrays 每個level的列表。 讓我們定義我們的grids_maker function

def grids_maker(arrays_list, colnames=list('xyzg')):
    # 0- The idea behind `list('xyzg')` is only to change the order
    #    of names, not the names as such. In case for example you
    #    want to use another component than the third to organize
    #    your planes.
    # 1- Instantiate a dataframe so as to minimize the modification
    #    of the function copied/pasted pasted from
    #    https://stackoverflow.com/a/54075350/4194079
    # 2- Pandas is also going to do some other jobs for us, such as
    #    stacking arrays, etc....
    df = pd.DataFrame(arrays_list, columns=colnames)

    # Make things more legible
    xy = df.loc[:, ['x', 'y']]
    x  = xy.x
    y  = xy.y
    z  = df.z
    g  = df.g
    reso_x = reso_y = 50
    interp = 'cubic' # or 'nearest' or 'linear'

    # Convert the 4d-space's dimensions into grids
    grid_x, grid_y = np.mgrid[
        x.min():x.max():1j*reso_x,
        y.min():y.max():1j*reso_y
    ]

    grid_z = si.griddata(
        xy, z.values,
        (grid_x, grid_y),
        method=interp
    )

    grid_g = si.griddata(
        xy, g.values,
        (grid_x, grid_y),
        method=interp
    )

    return {
        'x' : grid_x,
        'y' : grid_y,
        'z' : grid_z,
        'g' : grid_g,
    }

讓我們在 arrays 列表上使用grids_maker並獲取每個 z 級別的第 4 維的極值。

g_mins = []
g_maxs = []
lgrids = {}

for level, arrays_list in planes.items():
    lgrids[level] = grids = grids_maker(arrays_list)
    g_mins.append(grids['g'].min())
    g_maxs.append(grids['g'].max())

讓我們創建我們的(所有文件統一)色標並顯示 plot。

# Create the 4th color-rendered dimension
scam = plt.cm.ScalarMappable(
    norm=cm.colors.Normalize(min(g_mins), max(g_maxs)),
    cmap='jet' # see https://matplotlib.org/examples/color/colormaps_reference.html
)
fig = plt.figure()
ax  = fig.gca(projection='3d')
for grids in lgrids.values(): 
    scam.set_array([])   
    ax.plot_surface(
        grids['x'], grids['y'], grids['z'],
        facecolors  = scam.to_rgba(grids['g']),
        antialiased = True,
        rstride=1, cstride=1, alpha=None
    )
plt.show()

我很高興看到結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM