Question: I am trying to plot an arrow in Matplotlib as shown in the following picture. The arrow's color changes gradually from black to blue from the tail to the head. I searched the existing answers, and I found a few relevant posts: Using Colormap with Annotate Arrow in Matplotlib, Matplotlib: How to get a colour-gradient as an arrow next to a plot?, Arrow with color gradient in matplotlib [duplicate] However, the arrow plotted in the previous answer is straight. Here, I need an arrow with the arc. I think normally this is achieved by using connectionstyle options with arc or rad. Unfortunately, it seems neither matplotlib.patches.FancyArrowPatch nor matplotlib.pyplot.annotate supports the color to be defined by colormap directly. Could you please tell me how I can do this?

Answer: Plotting multiple overlapping arrows of different lengths and colors might work. You can adjust their length by changing the tail shrinking factors like this: import matplotlib.pyplot as plt import matplotlib.cm as cm from matplotlib.colors import LinearSegmentedColormap, ListedColormap import numpy as np def annotation_with_arc_arrow(ax, text, xy, xytext, color, headwidth, shrinkA, text_alpha=1): """Annotates a certain point on a plot with a simple arrow of a specified color, head width, shrinkA factor, and text alpha value (to be able to generate transparent text)""" text_props = {'alpha': text_alpha} ax.annotate(text, xy=xy, xycoords='data', xytext=xytext, textcoords='data', size=20, arrowprops=dict(facecolor=color, ec='none', arrowstyle='simple, head_width={0}'.format(headwidth), shrinkA=shrinkA, connectionstyle="arc3,rad=0.3" ), **text_props ) def gradient_annotation(ax, text, xy, xytext, cmap): """Annotates a certain point on a plot using a bent arrow with gradient color from tail to head""" # draw a headless arrow of the very first color from the map, with text annotation_with_arc_arrow(ax, text, xy, xytext, cmap(0), 0, 0) # draw many overlapping headless arrows of varying colors and shrinkA factors with transparent text last_cmap_index = cmap.N-1 for i in range(1, last_cmap_index): annotation_with_arc_arrow(ax, text, xy, xytext, cmap(i), 0, i, 0) # finally, draw an arrow of the very last color and shrinkA factor having a head of size 0.5 and transparent text annotation_with_arc_arrow(ax, text, xy, xytext, cmap(last_cmap_index), 0.5, last_cmap_index, 0) ax = plt.subplot(111) # generate a custom blue-black colormap N = 256 vals = np.ones((N, 4)) vals[:, 0] = np.linspace(0, 0, N) vals[:, 1] = np.linspace(0, 0, N) vals[:, 2] = np.linspace(0, 1, N) cmap = ListedColormap(vals) gradient_annotation(ax, 'Test', (0.2, 0.2), (0.8, 0.8), cmap) plt.show()  The text annotation and arrow's head should be drawn only once to have a relatively clean result:  Unfortunately, many other colormaps and arrow styles produce a bit dirty result with this solution. Perhaps you should try various ways of changing colors, setting shrinking factors, and choosing the "drawing direction" of the arrow (from tail to head or from head to tail). UPDATE: Alternatively, you could define arrow lengths by drawing a transparent head patch (patchB) of a gradually increasing radius each time you draw an arrow: import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap, ListedColormap import numpy as np import math import matplotlib.patches as mpatches def annotation_with_arc_arrow(ax, text, xy, xytext, color, headwidth, patchB_radius, text_alpha=1): """Annotates a certain point on a plot with a simple arrow of a specified color, head width, patchB radius, and text alpha value (to be able to generate transparent text)""" text_props = {'alpha': text_alpha} # transparent circle, limiting the arrow patchB = mpatches.Circle(xy, patchB_radius, alpha=0) ax.add_artist(patchB) ax.annotate(text, xy=xy, xycoords='data', xytext=xytext, textcoords='data', size=20, arrowprops=dict(facecolor=color, ec='none', arrowstyle='simple, head_width={0}'.format(headwidth), patchB=patchB, connectionstyle="arc3,rad=0.3" ), **text_props ) def gradient_annotation(ax, text, xy, xytext, cmap): """Annotates a certain point on a plot using a bent arrow with gradient color from tail to head""" # get the absolute differences in coordinates of the annotated point and the text dx = abs(xy[0] - xytext[0]) dy = abs(xy[1] - xytext[1]) # make those differences slightly smaller to compute a slightly smaller patch radius dx = dx - dx/50 dy = dy - dy/50 # get a radius, which is slightly smaller than the distance between the annotated point and the text r = math.sqrt(dx**2 + dy**2) # draw an arrow of the very first color from the map, with a head and text annotation_with_arc_arrow(ax, text, xy, xytext, cmap(0), 0.5, 0) # draw many overlapping headless arrows of varying colors and patchB radii, with transparent text # transparent patchB with a gradually increasing radius limits the arrow size for i in range(1, cmap.N): # compute a fraction of the maximum patchB radius r_i = r * (i/cmap.N) annotation_with_arc_arrow(ax, text, xy, xytext, cmap(i), 0, r_i, 0) ax = plt.subplot(111) # generate a custom blue-black colormap N = 256 vals = np.ones((N, 4)) vals[:, 0] = np.linspace(0, 0, N) vals[:, 1] = np.linspace(0, 0, N) vals[:, 2] = np.linspace(1, 0, N) cmap = ListedColormap(vals) gradient_annotation(ax, 'Test', (0.2, 0.2), (0.8, 0.8), cmap) plt.show()  This code produces a nearly identical picture:  But it allows you to safely rescale the picture without losing the original gradient color. The result might look a bit ugly if the arrow is very wide though. You might need to adjust the distribution of colors in the color map.