代码之家  ›  专栏  ›  技术社区  ›  moss_xyz

使用Matplotlib的AuxTransformBox旋转艺术家,导致意外行为

  •  0
  • moss_xyz  · 技术社区  · 11 月前

    首先:完全开放给其他可能完成同样事情的方法——我认为这是实现这一目标的最直接的方法。

    首先导入以下模块:

    import matplotlib
    import matplotlib.artist
    import matplotlib.lines
    import matplotlib.pyplot
    import matplotlib.patches
    import matplotlib.patheffects
    import matplotlib.offsetbox
    import matplotlib.transforms
    

    问题1:嵌套式辅助变压器箱

    假设我想创建一条2英寸长、旋转45度的线:

    # Creating a 5x5 plot
    fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
    # Creating a line
    line = matplotlib.lines.Line2D([0,2],[2,2])
    # This box will scale and rotate
    atb = matplotlib.offsetbox.AuxTransformBox(fig.dpi_scale_trans + matplotlib.transforms.Affine2D().rotate_deg(45))
    # Adding the line to the box
    atb.add_artist(line)
    # AOB will contain the final artist, and is used for centering
    aob = matplotlib.offsetbox.AnchoredOffsetbox(loc="center", child=atb, frameon=False, pad=0, borderpad=0)
    # Adding the AOB to the plot
    ax.add_artist(aob)
    

    这“有效”,尽管路线已经发生了很大变化: rotated and scaled line

    然而,这种使用两个嵌套在一起的AuxTransformBoxes的方法 工作-你可以看到隐藏在图形最底部边缘的线,没有旋转:

    # Creating a 5x5 plot
    fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
    # Creating a line
    line = matplotlib.lines.Line2D([0,2],[2,2])
    # This box will ONLY scale
    atb_scale = matplotlib.offsetbox.AuxTransformBox(fig.dpi_scale_trans)
    # Adding the line to the box
    atb_scale.add_artist(line)
    # This box will ONLY rotate
    atb_rotate = matplotlib.offsetbox.AuxTransformBox(matplotlib.transforms.Affine2D().rotate_deg(45))
    # Adding the previous atb to this one
    atb_rotate.add_artist(atb_scale)
    # AOB will contain the final artist, and is used for centering
    aob = matplotlib.offsetbox.AnchoredOffsetbox(loc="center", child=atb_rotate, frameon=False, pad=0, borderpad=0)
    # Adding the AOB to the plot
    ax.add_artist(aob)
    

    line scaled not rotated

    重复此过程,但打开最终AOB的框架,表明AOB应该在哪里,但其中包含的线条没有在其中正确绘制。

    # Creating a 5x5 plot
    fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
    # Creating a line
    line = matplotlib.lines.Line2D([0,2],[2,2])
    # This box will ONLY scale
    atb_scale = matplotlib.offsetbox.AuxTransformBox(fig.dpi_scale_trans)
    # Adding the line to the box
    atb_scale.add_artist(line)
    # This box will ONLY rotate
    atb_rotate = matplotlib.offsetbox.AuxTransformBox(matplotlib.transforms.Affine2D().rotate_deg(45))
    # Adding the previous atb to this one
    atb_rotate.add_artist(atb_scale)
    # AOB will contain the final artist, and is used for centering
    aob = matplotlib.offsetbox.AnchoredOffsetbox(loc="center", child=atb_rotate, frameon=True, pad=0, borderpad=0)
    # Adding the AOB to the plot
    ax.add_artist(aob)
    

    enter image description here

    为什么会是这样?嵌套的偏移框有时确实有效,但你能不嵌套吗 AuxTransforBox 它们一起交互应用转换?

    问题2:旋转其他偏移框

    我希望将这些AuxTransformBoxes应用于其他类型的OffsetBoxes,例如混合文本和艺术家的HPacker和VPacker,但这似乎也不起作用。

    这是一个垂直堆叠文本区域和线条艺术家的代码片段:

    # Creating a 5x5 plot
    fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
    # Creating a line
    line = matplotlib.lines.Line2D([0,2],[2,2])
    # This box will ONLY scale
    atb = matplotlib.offsetbox.AuxTransformBox(fig.dpi_scale_trans)
    # Adding the line to the box
    atb.add_artist(line)
    # Creating a TextArea
    txt = matplotlib.offsetbox.TextArea("Example")
    # This will pack the atb and txt artists together vertically
    vpack = matplotlib.offsetbox.VPacker(children=[txt,atb], align="center")
    # AOB will contain the final artist, and is used for centering
    aob = matplotlib.offsetbox.AnchoredOffsetbox(loc="center", child=vpack, frameon=False, pad=0, borderpad=0)
    # Adding the AOB to the plot
    ax.add_artist(aob)
    

    enter image description here

    然而,当所有内容都放在一个 AuxTransformBox 旋转(AnchoredOffsetbix的框架保持在这里):

    # Creating a 5x5 plot
    fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
    # Creating a line
    line = matplotlib.lines.Line2D([0,2],[2,2])
    # This box will ONLY scale
    atb_scale = matplotlib.offsetbox.AuxTransformBox(fig.dpi_scale_trans)
    # Adding the line to the box
    atb_scale.add_artist(line)
    # Creating a TextArea
    txt = matplotlib.offsetbox.TextArea("Example")
    # This will pack the atb and txt artists together vertically
    vpack = matplotlib.offsetbox.VPacker(children=[txt,atb_scale], align="center")
    # This box will ONLY rotate
    atb_rotate = matplotlib.offsetbox.AuxTransformBox(matplotlib.transforms.Affine2D().rotate_deg(45))
    # Adding the vpacker
    atb_rotate.add_artist(vpack)
    # AOB will contain the final artist, and is used for centering
    aob = matplotlib.offsetbox.AnchoredOffsetbox(loc="center", child=atb_rotate, frameon=True, pad=0, borderpad=0)
    # Adding the AOB to the plot
    ax.add_artist(aob)
    

    enter image description here

    同样,合成艺术家位于屏幕底部,不考虑AnchoredOffsetBox试图将其放置的位置。为什么会出现这种情况?

    0 回复  |  直到 11 月前