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