заполненная 3D гистограмма из 2D гистограммы с графиком - PullRequest
0 голосов
/ 27 февраля 2020

Я сделал график с точным кодом, размещенным здесь . Это почти то, что я хочу, но я бы хотел, чтобы кусочки 2D-гистограммы были заполнены, а не просто линией. Поэтому я добавляю параметр surfaceaxis=0, как я нашел в этом примере. Я получаю следующее изображение:

enter image description here

Я вижу, что код вроде «пытается» делать то, что я хочу, но не совсем. Я пробовал другие варианты, такие как go.Surface или go.Isosurface, но не работал.

Мой код:

# imports
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
from pdb import set_trace

pio.renderers.default = 'browser'

# data
np.random.seed(123)
df = pd.DataFrame(np.random.normal(50, 5, size=(300, 4)), columns=list('ABCD'))

# plotly setup
fig = go.Figure()

# data binning and traces
for i, col in enumerate(df.columns):
    a0 = np.histogram(df[col], bins=10, density=False)[0].tolist()
    a0 = np.repeat(a0, 2).tolist()
    a0.insert(0, 0)
    a0.append(0)
    a1 = np.histogram(df[col], bins=10, density=False)[1].tolist()
    a1 = np.repeat(a1, 2)
    # set_trace()

    fig.add_traces(go.Scatter3d(x=[i] * len(a0), y=a1, z=a0,
                                mode='lines',
                                name=col,
                                surfaceaxis=0
                                )
                   )

    # fig.add_traces(go.Surface(x=[i] * len(a0), y=a1, z=a0))
    # fig.add_traces(go.Isosurface(x=[i] * len(a0), y=a1, z=a0))
fig.show()

1 Ответ

1 голос
/ 02 марта 2020

Итак, здесь , @empet дал мне решение.

Код:

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

def triangulate_histogtam(x, y, z):

    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") 
    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)

# data
np.random.seed(123)
df = pd.DataFrame(np.random.normal(50, 5, size=(300, 4)), columns=list('ABCD'))

# plotly setup
fig = go.Figure()

# data binning and traces
bins = 10

bar_color = ['#e763fa', '#ab63fa', '#636efa', '#00cc96']
for m, col in enumerate(df.columns):
    a0=np.histogram(df[col], bins=bins, density=False)[0].tolist()
    a0=np.repeat(a0,2).tolist()
    a0.insert(0,0)
    a0.pop()
    a0[-1]=0
    a1=np.histogram(df[col], bins=bins-1, density=False)[1].tolist()
    a1=np.repeat(a1,2)

    verts, tri = triangulate_histogtam([m]*len(a0), a1, a0)
    x, y, z = verts.T
    I, J, K = tri.T
    fig.add_traces(go.Mesh3d(x=x, y=y, z=z, i=I, j=J, k=K, color=bar_color[m], opacity=0.7))

fig.update_layout(width=700, height=700, scene_camera_eye_z=0.8)

Результат:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...