pyplot:带有FancyArrowPatch的虚线 [英] pyplot: Dotted line with FancyArrowPatch

查看:34
本文介绍了pyplot:带有FancyArrowPatch的虚线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 python matplotlib.pyplot 生成复杂的图形输出.我想将 dotted 线型与 FancyArrowPatch 结合使用,但未能这样做.

MWE:

 将matplotlib.pyplot导入为plt导入matplotlib.patches作为补丁style ="Simple,head_width = 4,head_length = 8"linestyle="dotted" # 或 "solid"kw = dict(arrowstyle=style, linestyle=linestyle, color="b", connectionstyle="arc3,rad=1")plt.gca().add_patch(patches.FancyArrowPatch((0,1), (1,1), **kw))plt.savefig("MWE.pdf")

这会生成以下图像:

但是,我想得到类似的东西:

问题:我必须在MWE中进行哪些更改才能获得较低的图像?

如评论中所述,我怀疑是否有可能轻松更改FancyArrowPatch的线条样式.这实际上是一个多边形意义上的补丁,由 13 个点组成,这些点由线连接.如果更改线型,则不能仅对补丁的一部分进行更改.

一个选项可能确实将补丁分成箭头头部和尾部.对于尾部,您只需取其一部分并沿这些点创建一条新线.可以给该行自己的线型.头部可能会保留一个填充的色块,您可以为其选择其他线型.

您可以通过arrow.get_path() 获取原始箭头的路径.请注意,这将修复坐标,即箭头的所有变换都将丢失.因此,您需要确保仅在设置了最终轴限制和图形大小后才执行此操作,并且如果稍后更改其中任何一个都会以不希望的方式挤压箭头.

 将matplotlib.pyplot导入为plt导入 matplotlib.path导入matplotlib.patches作为补丁style="简单,head_width=40,head_length=80"kw = dict(arrowstyle = style,linestyle = None,lw = 1,color ="b",connectionstyle ="arc3,rad = 0.2")箭头 = 补丁.FancyArrowPatch((0,1), (1,1), **kw)plt.gca().add_patch(箭头)plt.gca().axis([0,1.03,0,1.1])def split_arrow(arrow, color_tail="C0",color_head="C0",ls_tail="-", ls_head="-",lw_tail=1.5, lw_head=1.5):v1 = arrow.get_path().vertices [0:3 ,:]c1 = arrow.get_path().codes [0:3]p1 = matplotlib.path.Path(v1,c1)pp1 =补丁.PathPatch(p1,color = color_tail,linestyle = ls_tail,fill = False,lw = lw_tail)arrow.axes.add_patch(pp1)v2 = arrow.get_path().vertices [3:8 ,:]c2 = arrow.get_path().codes[3:8]c2 [0] = 1p2 = matplotlib.path.Path(v2,c2)pp2 = patch.PathPatch(p2, color=color_head, lw=lw_head, linestyle=ls_head)arrow.axes.add_patch(pp2)箭头.remove()split_arrow(箭头,color_tail="深红色",color_head="limegreen",ls_tail="--", lw_tail=3)plt.show()

I am using python and matplotlib.pyplot to generate a complex graphical output. I'd like to use a dotted linestyle in conjunction with FancyArrowPatch but failed to do so.

MWE:

import matplotlib.pyplot as plt
import matplotlib.patches as patches

style="Simple,head_width=4,head_length=8"
linestyle="dotted" # or "solid"
kw = dict(arrowstyle=style, linestyle=linestyle, color="b", connectionstyle="arc3,rad=1")
plt.gca().add_patch(patches.FancyArrowPatch((0,1), (1,1), **kw))
plt.savefig("MWE.pdf")

This generates the following image:

However, I'd like to get something like:

Question: What do I have to change in my MWE to get the lower image?

解决方案

As said in the comments, I doubt that it is possible, to easily change the linestyle of the FancyArrowPatch. This is really a patch in the sense of a polygon, consisting of 13 points which are connected by lines. If changing the linestyle you cannot change it for only part of the patch.

An option might indeed to split the patch into the arrow head and the tail. For the tail you would only take part of it and create a new line along those points. This line can be given its own linestyle. The head may stay a filled patch, for which you may choose a different linestyle.

You may get the path of the original arrow by arrow.get_path(). Note that this will fix the coordinates, i.e. all transforms of the arrow will be lost. Hence you need to make sure to do this only once the final axes limits and figure size have been set, and that if changing any of them later on will squeeze the arrow in an undesired manner.

import matplotlib.pyplot as plt
import matplotlib.path
import matplotlib.patches as patches


style="Simple,head_width=40,head_length=80"
kw = dict(arrowstyle=style, linestyle=None, lw=1,color="b",connectionstyle="arc3,rad=0.2")
arrow = patches.FancyArrowPatch((0,1), (1,1), **kw)

plt.gca().add_patch(arrow)
plt.gca().axis([0,1.03,0,1.1])

def split_arrow(arrow, color_tail="C0",color_head="C0", 
                ls_tail="-", ls_head="-",lw_tail=1.5, lw_head=1.5):    
    v1 = arrow.get_path().vertices[0:3,:]
    c1 = arrow.get_path().codes[0:3]
    p1 = matplotlib.path.Path(v1,c1)
    pp1 = patches.PathPatch(p1, color=color_tail, linestyle=ls_tail, 
                            fill=False, lw=lw_tail)
    arrow.axes.add_patch(pp1)

    v2 = arrow.get_path().vertices[3:8,:]
    c2 = arrow.get_path().codes[3:8]
    c2[0] = 1
    p2 = matplotlib.path.Path(v2,c2)
    pp2 = patches.PathPatch(p2, color=color_head, lw=lw_head, linestyle=ls_head)
    arrow.axes.add_patch(pp2)
    arrow.remove()

split_arrow(arrow, color_tail="crimson",color_head="limegreen", 
                ls_tail="--", lw_tail=3)

plt.show()

这篇关于pyplot:带有FancyArrowPatch的虚线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆