Plotly - 如何绘制圆柱体?

2024-03-29

I have a function plotting the cylinder, using matplotlib. enter image description here

我想知道如何使用情节来做同样的事情?

下面是我绘制圆柱体的 matplotlib 函数:

        #function to plot the cylinder
        def _plotCylinder(self, ax, x, y, z, dx, dy, dz, color='red',mode=2):
            """ Auxiliary function to plot a Cylinder  """
            # plot the two circles above and below the cylinder
            p = Circle((x+dx/2,y+dy/2),radius=dx/2,color=color,ec='black')
            p2 = Circle((x+dx/2,y+dy/2),radius=dx/2,color=color,ec='black')
            ax.add_patch(p)
            ax.add_patch(p2)
            art3d.pathpatch_2d_to_3d(p, z=z, zdir="z")
            art3d.pathpatch_2d_to_3d(p2, z=z+dz, zdir="z")
            # plot a circle in the middle of the cylinder
            center_z = np.linspace(0, dz, 15)
            theta = np.linspace(0, 2*np.pi, 15)
            theta_grid, z_grid=np.meshgrid(theta, center_z)
            x_grid = dx / 2 * np.cos(theta_grid) + x + dx / 2
            y_grid = dy / 2 * np.sin(theta_grid) + y + dy / 2
            z_grid = z_grid + z
            ax.plot_surface(x_grid, y_grid, z_grid,shade=False,fc=color,ec='black',alpha=1,color=color)
    x,y,z = item.position
    [w,h,d] = item.getDimension()
    # plot item of cylinder
    self._plotCylinder(axGlob, float(x), float(y), float(z), float(w),float(h),float(d),color=color,mode=2)

更新 - 用于绘制立方体类型项目的当前代码

### PLOTLY ###
# https://plotly.com/python/3d-mesh/#mesh-cube
def vertices(xmin=0, ymin=0, zmin=0, xmax=1, ymax=1, zmax=1):
    return {
        "x": [xmin, xmin, xmax, xmax, xmin, xmin, xmax, xmax],
        "y": [ymin, ymax, ymax, ymin, ymin, ymax, ymax, ymin],
        "z": [zmin, zmin, zmin, zmin, zmax, zmax, zmax, zmax],
        "i": [7, 0, 0, 0, 4, 4, 6, 1, 4, 0, 3, 6],
        "j": [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3],
        "k": [0, 7, 2, 3, 6, 7, 1, 6, 5, 5, 7, 2],
    }



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

# take a packer item and build parameters to a plotly mesh3d cube
def packer_to_plotly(item):
    colors = ["crimson", "limegreen", "green", "red", "cyan", "magenta", "yellow"]

    ret = vertices(
        *item.position, *[sum(x) for x in zip(item.position, item.getDimension())]
    )
    ret["name"] = item.name
    ret["color"] = colors[ord(item.name.split("_")[0][-1]) - ord("A")]
    return ret

# create a multi-plot figure for each bin
# fig = make_subplots(rows=len(packer.bins), cols=1, specs=[[{"type":"mesh3d"}], [{"type":"mesh3d"}]])
fig = go.Figure()

# add a trace for each packer item
for row, pbin in enumerate(packer.bins):
    for item in pbin.items:
        fig.add_trace(go.Mesh3d(packer_to_plotly(item)))

    # sorting out layout, prmarily aspect ratio
    fig.update_layout(
        margin={"l": 0, "r": 0, "t": 0, "b": 0},
        autosize=False,
        scene=dict(
            camera=dict(
                # eye=dict(x=0.1, y=0.1, z=1.5)
            ),
            aspectratio=dict(x=1, y=.2, z=0.2),
            aspectmode="manual",
        ),
    )


    # push data into a data frame to enable more types of analysis
df = pd.DataFrame(
    [
        {
            "bin_name": b.partno,
            "bin_index": i,
            **packer_to_plotly(item),
            **{d: v for v, d in zip(item.getDimension(), list("hwl"))},
            **{d + d: v for v, d in zip(item.position, list("xyz"))},
        }
        for i, b in enumerate(packer.bins)
        for item in b.items
    ]
)

# create a figure for each container (bin)
for pbin, d in df.groupby("bin_name"):
    fig = go.Figure()
    xx = []
    yy = []
    zz = []

    # create a trace for each box (bin)
    for _, r in d.iterrows():
        fig.add_trace(
            go.Mesh3d(r[["x", "y", "z", "i", "j", "k", "name", "color"]].to_dict())
        )
        xx += [r.xx, r.xx + r.h, r.xx + r.h, r.xx, r.xx, None] * 2 + [r.xx] * 5 + [None]
        yy += [r.yy, r.yy, r.yy + r.w, r.yy + r.w, r.yy, None] * 2 + [
            r.yy,
            r.yy + r.w,
            r.yy + r.w,
            r.yy,
            r.yy,
            None,
        ]
        zz += (
            [r.zz] * 5
            + [None]
            + [r.zz + r.l] * 5
            + [None]
            + [r.zz, r.zz, r.zz + r.l, r.zz + r.l, r.zz, None]
        )

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

    x, y, z = parallelipipedic_frame(0, 1202.4, 0, 235, 0, 269.7)

    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(
        showlegend=False,
        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",
        ),
    )
fig.show()

我有机会花一些时间来解决创建圆柱体网格的问题,因此致力于三角测量。

这是结果。主要功能是cylinder_traces:它返回go.Surface跟踪,并且可选go.Scatter3d代表线框网格的痕迹。

import plotly.graph_objects as go
import numpy as np

def slice_triangles(z, n, i, j, k, l):
    """Create the triangles of a single slice"""
    return [[z, j, i], [i, j, l], [l, j, k], [k, n, l]]

def cylinder_mesh(r, xs, ys, zs, h, n_slices=40):
    """Create a cylindrical mesh"""
    theta = np.linspace(0, 2 * np.pi, n_slices + 1)
    x = xs + r * np.cos(theta)
    y = ys + r * np.sin(theta)
    z1 = zs + 0 * np.ones_like(x)
    z2 = (zs + h) * np.ones_like(x)
    
    # index of the final point in the mesh
    n = n_slices * 2 + 1
    
    # build triangulation
    triangles = []
    for s in range(1, n_slices + 1):
        j = (s + 1) if (s <= n_slices - 1) else 1
        k = j + n_slices if (s <= n_slices - 1) else n_slices + 1
        l = s + n_slices
        triangles += slice_triangles(0, n, s, j, k, l)
    triangles = np.array(triangles)
    
    # coordinates of the vertices
    x_coords = np.hstack([xs, x[:-1], x[:-1], xs])
    y_coords = np.hstack([ys, y[:-1], y[:-1], ys])
    z_coords = np.hstack([zs, z1[:-1], z2[:-1], (zs + h)])
    vertices = np.stack([x_coords, y_coords, z_coords]).T
    
    return vertices, triangles, x, y, z1, z2

def cylinder_traces(r, xs, ys, zs, h, n_slices=40, show_mesh=True, n_sub=4, surface_kw={}, line_kw={}):
    """
    r : radius
    xs, ys, zs : start position of the cylinder
    h : height of the cylinder
    n_slices : number of slices in the circumferential direction
    show_mesh : wheter to display pseudo-wireframe
    n_sub : number of subdivision in along the height for the pseudo-wireframe
    surface_kw : customize the appearance of the surface
    line_kw : customize the appearance of the wireframe
    """
    vertices, triangles, x, y, z1, z2 = cylinder_mesh(r, xs, ys, zs, h, n_slices)
    surface = go.Mesh3d(
        x=vertices[:, 0], y=vertices[:, 1], z=vertices[:, 2],
        i=triangles[:, 0], j=triangles[:, 1], k=triangles[:, 2],
        **surface_kw)
    
    traces = [surface]
    if not show_mesh:
        return traces
    
    line_kw.setdefault("showlegend", False)
    # horizontal mesh lines
    zsubs = np.linspace(zs, zs + h, n_sub + 1)
    for zc in zsubs:
        traces.append(go.Scatter3d(x=x, y=y, z=zc*np.ones_like(x), mode="lines", **line_kw))
    # vertical mesh lines
    for _x, _y in zip(x, y):
        traces.append(go.Scatter3d(x=[_x, _x], y=[_y, _y], z=[zs, zs + h], mode="lines", **line_kw))
    return traces

fig = go.Figure()
fig.add_traces(
    cylinder_traces(2, 5, 3, 1, 4, 20, n_sub=4, line_kw={"line_color":"#202020", "line_width": 3})
)
fig

原答案:OP 可能与气缸盖有关。所以,我们需要创建:

  • 圆柱壁的表面,与您使用 matplotlib 所做的类似。
  • 底盖的表面。
  • 顶盖的表面。

注意:在下图中,我对气缸壁和盖子使用了不同的颜色,以便更好地可视化它们。

import numpy as np
import plotly.graph_objects as go

def cylinder(x, y, z, r, dz):
    """Create a cylindrical mesh located at x, y, z, with radius r and height dz"""
    center_z = np.linspace(0, dz, 15)
    theta = np.linspace(0, 2*np.pi, 15)
    theta_grid, z_grid = np.meshgrid(theta, center_z)
    x_grid = r * np.cos(theta_grid) + x
    y_grid = r * np.sin(theta_grid) + y
    z_grid = z_grid + z
    return x_grid, y_grid, z_grid

def circle(x, y, z, r):
    """Create a circular mesh located at x, y, z with radius r"""
    r_discr = np.linspace(0, r, 2)
    theta_discr = np.linspace(0, 2*np.pi, 15)
    r_grid, theta_grid = np.meshgrid(r_discr, theta_discr)
    x_circle = r_grid * np.cos(theta_grid) + x
    y_circle = r_grid * np.sin(theta_grid) + y
    z_circle = np.zeros_like(x_circle) + z
    return x_circle, y_circle, z_circle

# cylinder mesh
x_cyl, y_cyl, z_cyl = cylinder(0, 0, 0, 2, 8)
# bottom cap
x_circle1, y_circle1, z_circle1 = circle(0, 0, 0, 2)
# top cap
x_circle2, y_circle2, z_circle2 = circle(0, 0, 8, 2)

colorscale = [[0, '#636EFA'],
             [1, '#636EFA']]

fig = go.Figure([
    go.Surface(x=x_cyl, y=y_cyl, z=z_cyl, colorscale=colorscale, showscale=False, opacity=0.5),
    go.Surface(x=x_circle1, y=y_circle1, z=z_circle1, showscale=False, opacity=0.5),
    go.Surface(x=x_circle2, y=y_circle2, z=z_circle2, showscale=False, opacity=0.5),
])
fig
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Plotly - 如何绘制圆柱体? 的相关文章

随机推荐

  • 有没有办法在Python中按第n个分隔符分割字符串?

    例如 如果我有以下字符串 这是一个字符串 我可以将它分割为每个第二个 而不是每个 以便它返回两个值 this is 和 a string 而不是返回四个值吗 这是另一个解决方案 span 2 words this is a string s
  • 使用jquery求div内元素的总和

    我正在对一组用户进行排序 我有 4 个分组 如下所示 显示 2 个 div class groupWrapper div class groupItem div class itemHeader div class first John d
  • 如何在不链接libc.so的情况下访问段寄存器?

    我正在尝试在 Ubuntu 20 10 上使用 NASM 版本 2 15 04 在 64 位程序集中编写一个简单的堆栈金丝雀 执行下面的代码会导致在使用命令进行汇编和链接时出现分段错误nasm felf64 canary asm ld ca
  • Twitter iOS Streaming API:未收到数据

    我正在尝试修改Apple使用Twitter API的示例代码 以便我可以使用流API来过滤推文 我正在尝试实施针对此问题建议的方法 TWRequest 是否适用于 Twitter 流 API https stackoverflow com
  • Twilio:此电话号码无法发送消息

    我现在有一个 Twilio 测试帐户 我获得了一个比利时电话号码 并验证了我自己的手机号码 我正在尝试从分配的 Twilio 号码向我的手机号码发送简单的 SMS 消息 但这不起作用 仪表板显示 此电话号码无法发送消息 但在消息常见问题解答
  • 如何使用 WSDL

    我正在开发 WSDL 应用程序 但实际上我不明白什么是 wsdl 参数以及我将如何处理返回的 XML 例如 https adwords google com api adwords cm v201309 CampaignService ws
  • 如何防止响应式网页上的水平滚动?

    我正在使用 twitter bootstrap 来使我的应用程序具有响应能力 当我将浏览器窗口的宽度缩小到最小尺寸或在移动设备 例如 iPhone 上查看页面时 用户可以水平滚动 水平滚动量很小 但我想将其全部删除 我相信这是由于我包含的
  • 删除R中一组行中的某些行

    假设我有这个数据集 Id Name Price sales Profit Month Category Mode Supplier 1 A 2 0 0 1 X K John 1 A 2 0 0 2 X K John 1 A 2 5 8 3
  • Swift 中设置和读取 Bool 是原子操作吗?

    正如标题所示 很简单 基本上 在这个例子中 我们是否可以获得无效状态 var myBool false Thread 1 while true if randomEvent myBool true Thread 2 while true i
  • 服务器安全和通过 Rest 访问 OrientDB

    我猜这是一个令人尴尬的初学者问题 无论如何 在 OrientDB 文档的 服务器安全 下 我们发现 虽然 OrientDB Server 可以充当常规 Web 服务器 但不建议您将其直接公开到 Internet 或公共网络 相反 始终将 O
  • 在 Java 32 位和 Java 64 位之间切换

    我刚刚发现 如果我使用 64 位 JDK Apache Tomcat 无法作为 Windows 服务运行 因此我在 Windows 上另外安装了 Java 32 位 问题是当我使用 java version 检查 java 版本时 它仍然显
  • 从 wtforms 和flask-sqlalchemy 中的数据库查询中获取选择

    我正在使用 Flask SQLAlchemy 和 WTForms 开发一个 Web 应用程序 我想得到我的选择选择字段通过我的数据库查询 有更多细节 my query my table query with entities My Enti
  • 日志文件的合适大小(以字节为单位)是多少?

    我正在使用蟒蛇logging http docs python org library logging html simple examples模块旋转文件处理器 http docs python org library logging h
  • BasicHttpBinding 端点配置中的 bindingConfiguration 属性负责什么?

    因此 我正在为 WCF 服务配置端点 我对整个服务几乎没有经验 但一直在使用它们的项目中 我大致了解端点中除一个属性之外的每个属性的作用 绑定配置 这是我的代码的模糊版本 实际信息是专有的
  • vuejs - 计算不能与 props 一起使用

    我正在使用 props 来更新子组件中的网站内容 这基本上是这样工作的
  • 在 Firestore 中安全保存数据

    Firestore 文档shows https firebase google com docs firestore security rules query examples https firebase google com docs
  • Groovy:从文件中读取一系列行

    我有一个文本文件 其中包含大约 2 000 000 行的大量数据 使用以下代码片段浏览文件很容易 但这不是我需要的 def f new File input txt f eachLine Some code here 我只需要从文件中读取特
  • 函数指针作为参数

    我尝试调用一个不带参数作为函数指针传递的函数 但我无法使其工作 void disconnectFunc void D setDisconnectFunc void func disconnectFunc func void D discon
  • TPL 是否可以在多个线程上运行任务?

    欢迎特定于 Mono Xamarin 的答案 我正在使用 Task Run 运行 System Threading Tasks TPL 是否会在任务执行的生命周期内将创建的任务分配给单个线程 或者创建的任务是否有可能在运行时被抢占 然后再次
  • Plotly - 如何绘制圆柱体?

    I have a function plotting the cylinder using matplotlib 我想知道如何使用情节来做同样的事情 下面是我绘制圆柱体的 matplotlib 函数 function to plot the