Skip to content

"Classical" zero-axis plot with arrows and symmetric ticks seems to be impossible #17157

Closed
@m-oliver

Description

@m-oliver

Bug report

Bug summary

I am trying to use matplotlib to produce classical "Mathematics-style" plots in production quality, with a cross of coordinate axes through the origin, arrow tips on the axes, and symmetic ("inout") ticks (in fact, since the entire plot is symmetric, there is no in or out, so asymmetric tick placement looks out of place).

Following axisartist-demo-axisline-style from the Matplotlib gallery, I am able to get the arrows, but it fails on the symmetric ticks. Using an alternative incantation which a student of mine came up with (I don't know where from), the symmetric ticks work, but we don't seem to be able to get arrow heads on the axes.

Both examples also differ in other placement decisions (why???), none is optimal, but all other things look fixable with some effort.

I am not sure whether this is a documentation bug or a code bug, but what bugs me is the apparent impossibility to meet the two requirements, arrow heads and symmetric ticks, at once.

Code for reproduction

#! /usr/bin/env python3

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid.axislines import SubplotZero

plt.rcParams.update({'xtick.direction': "inout",
                     'ytick.direction': "inout"})

xx = np.linspace(-np.pi, np.pi, 200)

# from https://matplotlib.org/gallery/axisartist/demo_axisline_style.html#sphx-glr-gallery-axisartist-demo-axisline-style-py
fig = plt.figure()
ax = SubplotZero(fig, 111)
fig.add_subplot(ax)

for direction in ["xzero", "yzero"]:
    # adds arrows at the ends of each axis
    ax.axis[direction].set_axisline_style("-|>")
     
    # adds X and Y-axis from the origin
    ax.axis[direction].set_visible(True)

for direction in ["left", "right", "bottom", "top"]:
    # hides borders
    ax.axis[direction].set_visible(False)

ax.plot(xx, np.sin(xx))
plt.title("Arrow heads work, symmetric ticks don't")
plt.show()

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

ax.plot(xx, np.sin(xx))
plt.title("Symmetric ticks work, but how to get arrow heads?")
plt.show()

Actual outcome
test1
test2

Expected outcome

The first plot should just produce symmetric ticks, as requested in the rcParams. For the second one, it might be missing documentation, I just don't know how to proceed. The differences between the two versions are very strange, and not documented in any obvious place.

Matplotlib version

  • Operating system: Fedora 30
  • Matplotlib version: python3-matplotlib-3.0.3-2.fc30.x86_64
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.7.6
  • Jupyter version (if applicable): N/A
  • Other libraries: N/A

Default Fedora 30 install.

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