Skip to content

[ENH]: Improve plt.arrow default head shape #22379

Closed
@ianhi

Description

@ianhi

Problem

The default for the head width/length of the fancy arrow patch are not very good. See for example: https://philbull.wordpress.com/2012/04/05/drawing-arrows-in-matplotlib/

This means that in order to get a usable arrow you need to mess around with options such as head_length which can be tricky to learn about.

Proposed solution

Use a new heuristic for head sizing as a default behavior.

@kmdalton suggested the below function norm_arrow which you can see gives better defaults in two basic test cases.

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(2,2)

lims = (
    [-1, 1],
    [-10,10],
)

def norm_arrow(ax, x1, y1, x2, y2, head_scale=0.1, head_width=None, **kwargs):
    norm = np.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
    l = head_scale*norm
    w = head_width if head_width is not None else 0.5*l
    ax.arrow(x1, y1, x2, y2, head_width=w, head_length=l, length_includes_head=True, **kwargs)

axes[0][1].set_title("Norm based default")
axes[0][0].set_title("Current Default")

for axs, lim in zip(axes, lims):
    axs[0].set_ylim(lim)
    axs[0].set_xlim(lim)
    axs[1].set_ylim(lim)
    axs[1].set_xlim(lim)

    axs[0].arrow( 0, 0, lim[1]/2, lim[1]/2, fc="k", ec="k" )
    norm_arrow(axs[1], 0, 0, lim[1]/2, lim[1]/2, fc="k", ec="k" )

plt.show()

image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions