Search code examples
pythonplotlyaspect-ratiobin-packing

Plotly 3D plot with right aspect ratio


the relevant post is here: interactive 3D plot with right aspect ratio using plotly

For a further improvment, I am wondering how to plot a container frame according to the bin size, so the graph can display more clearly how much spare space is left, when container is not full? just like what is shown below:

enter image description here

UPADTE: drawing outer container frame

def parallelipipedic_frame(xm, xM, ym, yM, zm, zM):
    # defines the coords of each segment followed by None, if the line is
    # discontinuous
    x = [xm, xM, xM, xm, xm, None, xm, xM, xM, xm, xm, None, xm, xm, None, xM, xM,
         None, xM, xM, None, xm, xm]
    y = [ym, ym, yM, yM, ym, None, ym, ym, yM, yM, ym, None, ym, ym, None, ym, ym,
         None, yM, yM, None, yM, yM]
    z = [zm, zm, zm, zm, zm, None, zM, zM, zM, zM, zM, None, zm, zM, None, zm, zM,
         None, zm, zM, None, zm, zM]
    return x, y, z

x, y, z = parallelipipedic_frame(0, 1202.4, 0, 235, 0, 269.7)
# fig = go.Figure(go.Scatter3d(x=x, y=y, z=z, mode="lines", line_width=4))

fig.add_trace(
    go.Scatter3d(
        x=x,
        y=y,
        z=z,
        mode="lines",
        line_color="blue",
        line_width=2,
        hoverinfo="skip",
    )
)

ar = 4
xr = max(d["x"].max()) - min(d["x"].min())
fig.update_layout(
    title={"text": pbin, "y": 0.9, "x": 0.5, "xanchor": "center", "yanchor": "top"},
    margin={"l": 0, "r": 0, "t": 0, "b": 0},
    # autosize=False,
    scene=dict(
        camera=dict(eye=dict(x=2, y=2, z=2)),
        aspectratio={
            **{"x": ar},
            **{
                c: ((max(d[c].max()) - min(d[c].min())) / xr) * ar
                for c in list("yz")
            },
        },
        aspectmode="manual",
    ),
)

enter image description here


Solution

  • The frame consists of segments, and a segment is drawn between two points. Hence I cannot give the code for plottin the frame only from your length, width and height. I need the coordinates of the parallelipiped vertices, i.e. x.min(), x.max(), y.min(), y.max(), etc (see above), denoted xm, xM, ym, yM, zm, zM:

    import plotly.graph_objects as go
    
    def parallelipipedic_frame(xm, xM, ym, yM, zm, zM):
        #defines the coords of each segment followed by None, if the line is 
        discontinuous
        x = [xm, xM, xM, xm, xm, None, xm, xM, xM, xm, xm, None, xm, xm, None, xM, xM, 
             None, xM, xM, None, xm, xm]
        y = [ym, ym, yM, yM, ym, None, ym, ym, yM, yM, ym, None, ym, ym, None, ym, ym, 
             None, yM, yM,None, yM, yM]
        z= [zm, zm, zm, zm, zm, None, zM, zM, zM, zM, zM, None, zm, zM, None, zm, zM, 
            None, zm, zM, None, zm, zM]
        return x, y, z
    
    x, y, z= parallelipipedic_frame(2.3, 4.5, 0,5, 0, 2)
    fig=go.Figure(go.Scatter3d(x=x, y=y, z=z, mode="lines", line_width=4))
    fig.update_layout(width=600, height=450, font_size=11,  scene_aspectmode="data", 
                      scene_camera_eye=dict (x=1.45, y=1.45, z=1), template="none")
    fig.show()
    

    enter image description here