Fge
Fge

Reputation: 3

Draw arrows on matplotlib figure directly

I created a plot containing multiple subplots on a grid. The plots differ in two parameters, so I would like it to look like they ordered in a coordinate system.

I managed to plot lines using matplotlib.lines.Line2D() next to the subplots directly on the figure. But I would prefer to have an arrow instead of a line to make it more clear. (I can add the specific parameter values using fig.text().)

I'd like the blue lines to be arrows

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from itertools import product 

fig = plt.figure()
plotGrid = mpl.gridspec.GridSpec(2, 2)

x = np.linspace(0,10,10000)
y = [j* np.sin(x + i)  for i,j in product(range(2), range(1,3))]

for i in range(4):
    ax = plt.Subplot(fig, plotGrid[i])

    for sp in ax.spines.values():
        sp.set_visible(False)

    ax.plot(x,y[i], color = 'r')
    ax.set_xticks([])
    ax.set_yticks([])
    fig.add_subplot(ax)

all_axes = fig.get_axes()


#I would like these lines to be arrows  
blcorPosn = 0.08 #bottom corner position
l1 = mpl.lines.Line2D([blcorPosn,blcorPosn], [1, blcorPosn],
                      transform=fig.transFigure, fig)

l2 = mpl.lines.Line2D([blcorPosn, 1], [blcorPosn, blcorPosn],
                      transform=fig.transFigure, fig)

fig.lines.extend([l1, l2])

I'm not sure if this is the way to go. But I spend like a day on this by now and the only way I see so far to draw arrows is drawing them directly on an axes but thats not an option for me as far as I can see.

Also this is my first post here so advice on how to ask questions is highly appreciated. Thanks

Upvotes: 0

Views: 2593

Answers (1)

mfitzp
mfitzp

Reputation: 15545

You can replace the Line2D along each axis with a slightly modified call to FancyArrow patch. The main difference is that that origin and destination x,y coords are replaced with origin x,y and a x,y distance to draw. The values are also passed as parameters directly, not as lists:

l1 = mpl.patches.FancyArrow(blcorPosn, blcorPosn, 1, 0,
                            transform=fig.transFigure, figure=fig)

l2 = mpl.patches.FancyArrow(blcorPosn, blcorPosn, 0, 1,
                            transform=fig.transFigure, figure=fig)

The FancyArrow patch accepts a few other parameters to allow you to customise the appearance of the arrow including width (for line width), head_width and head_length.

Figure with axis arrows

Upvotes: 1

Related Questions