How to make 'fuller' axis arrows with matplotlib

matplotlib, python

Solution

My solution is essentially the same as nebffa's. I created a minimal example that calculates arrowhead width and length for the y-axis to match the one specified for the x-axis. I hope that this might be helpful to somebody else.

import pylab as pl

fig = pl.figure()
ax = fig.add_subplot(111)

x = pl.arange(-5,5,0.1)
ax.plot(x, x**2-8.8)

xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()

# removing the default axis on all sides:
for side in ['bottom','right','top','left']:
    ax.spines[side].set_visible(False)

# removing the axis ticks
pl.xticks([]) # labels
pl.yticks([])
ax.xaxis.set_ticks_position('none') # tick markers
ax.yaxis.set_ticks_position('none')

# wider figure for demonstration
fig.set_size_inches(4,2.2)

# get width and height of axes object to compute
# matching arrowhead length and width
dps = fig.dpi_scale_trans.inverted()
bbox = ax.get_window_extent().transformed(dps)
width, height = bbox.width, bbox.height

# manual arrowhead width and length
hw = 1./20.*(ymax-ymin)
hl = 1./20.*(xmax-xmin)
lw = 1. # axis line width
ohg = 0.3 # arrow overhang

# compute matching arrowhead length and width
yhw = hw/(ymax-ymin)*(xmax-xmin)* height/width
yhl = hl/(xmax-xmin)*(ymax-ymin)* width/height

# draw x and y axis
ax.arrow(xmin, 0, xmax-xmin, 0., fc='k', ec='k', lw = lw,
         head_width=hw, head_length=hl, overhang = ohg,
         length_includes_head= True, clip_on = False)

ax.arrow(0, ymin, 0., ymax-ymin, fc='k', ec='k', lw = lw,
         head_width=yhw, head_length=yhl, overhang = ohg,
         length_includes_head= True, clip_on = False)

# clip_on = False if only positive x or y values.

pl.savefig('arrow_axis.png', dpi = 300)

Produces:

Problem

I have the following code: ``` from mpl_toolkits.axes_grid.axislines import SubplotZero from matplotlib.transforms import BlendedGenericTransform import matplotlib.pyplot as plt import numpy if 1: fig = plt.figure(1) ax = SubplotZero(fig, 111) fig.add_subplot(ax) ax.axhline(linewidth=1.7, color="black") ax.axvline(linewidth=1.7, color="black") plt.xticks([1]) plt.yticks([]) ax.text(0, 1.05, 'y', transform=BlendedGenericTransform(ax.transData, ax.transAxes), ha='center') ax.text(1.05, 0, 'x', transform=BlendedGenericTransform(ax.transAxes, ax.transData), va='center') for direction in ["xzero", "yzero"]: ax.axis[direction].set_axisline_style("-|>") ax.axis[direction].set_visible(True) for direction in ["left", "right", "bottom", "top"]: ax.axis[direction].set_visible(False) x = numpy.linspace(-0.5, 1., 1000) ax.plot(x, numpy.sin(x*numpy.pi), linewidth=1.2, color="black") plt.show() ``` which produces the following image: The axis arrowheads look vestigial in comparison to the actual graph. How do I size them up a little so that they look normal with respect to the width of the axes. Also - it is difficult to see here, but the interior of the arrows is blue - how do I change that to black?

Original source