如何在plotly中绘制3D直方图?

问题描述 投票:0回答:1

我希望使用plotly重新创建张量板中可用的多直方图可视化:

各个直方图的绘制很简单,但我不知道如何对痕迹进行 3D 偏移。

我想我正在寻找一种在 3d 空间上堆叠 2d 轨迹(直方图)的方法,例如:

从那里我认为造型/透明度/相机位置的组合将使我完成剩下的工作。

我查看了

plotly
https://plotly.com/python/3d-charts/)中的3d图,但没有找到合适的解决方案。

结束可能是https://plotly.com/python/3d-surface-plots/

注意 5 年前的这个问题非常相似,但没有答案:如何在 Python 中使用 Plotly 绘制这种 3D 轴?

plotly plotly-python
1个回答
0
投票

我通过调整找到了解决方案:https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/8

我在这里分享它,作为遇到此问题的其他人的起点:


# Note that I'm using polars dataframes, but it's trivial to convert to pandas

import numpy as np
import pandas as pd
import plotly.graph_objects as go

df = pd.DataFrame(np.random.normal(50, 5, size=(30000, 4)), columns=list('ABCD')).pipe(pl.from_pandas)


def plot_stacked_histograms(df:pl.DataFrame, columns=None, bins=None):
    
    fig = go.Figure()
    
    if bins is None:
        bins = len(df)//20+1 # Heuristic - please select a more appropriate value if you have one
        
    if columns is None:
        columns = df.columns
        
    def triangulate_histogram(x:list[float], y:list[float], z:list[float]):
   
        if len(x)  != len(y) != len(z) :
            raise ValueError("The  lists x, y, z, must have the same length")
        
        n = len(x)
        if n % 2 :
            raise ValueError("The length of lists x, y, z must be an even number") 
        
        import numpy as np 
        
        pts3d = np.vstack((x, y, z)).T
        pts3dp = np.array([[x[2*k+1], y[2*k+1], 0] for k in range(1, n//2-1)])
        pts3d = np.vstack((pts3d, pts3dp))
        
        #triangulate the histogram bars:
        tri = [[0,1,2], [0,2,n]]
        for k, i  in zip(list(range(n, n-3+n//2)), list(range(3, n-4, 2))):
            tri.extend([[k, i, i+1], [k, i+1, k+1]])
        
        tri.extend([[n-3+n//2, n-3, n-2], [n-3+n//2, n-2, n-1]])     
         
        return pts3d, np.array(tri)
        
    def column_values_to_plottable_surface(column:np.array, traceId:int, color:int):
        a0=np.histogram(column, bins=bins, density=False)[0].tolist()
        a0=np.repeat(a0,2).tolist()
        a0.insert(0,0)
        a0.pop()
        a0[-1]=0
        a1=np.histogram(column, bins=bins-1, density=False)[1].tolist()
        a1=np.repeat(a1,2)
    
        verts, tri = triangulate_histogram([traceId]*len(a0), a1, a0)
        x, y, z = verts.T
        I, J, K = tri.T

        trace = go.Mesh3d(x=x, y=y, z=z, i=I, j=J, k=K, color=color, opacity=0.7)
        return trace
    
    for traceId, column in enumerate(df.select(columns).to_numpy().T):
        trace = column_values_to_plottable_surface(column, traceId=traceId, color=traceId)
        fig.add_traces(trace)
        
        
    scene_kwargs = dict(
        camera = dict(up=dict(x=0,y=1,z=2),eye=dict(x=2,y=2,z=1,)),
        aspectratio = dict(x=1, y=3, z=1),
        aspectmode = 'manual'
        )
                    
    fig.update_layout(width=1700, height=700, scene_camera_eye_z=0.8, scene=scene_kwargs)   
    return fig 


plot_stacked_histograms(df, bins=500)

© www.soinside.com 2019 - 2024. All rights reserved.