Skip to content

[Bug]: Setting ticks marks on a single spine doesn't work properly #25117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
WWakker opened this issue Jan 31, 2023 · 3 comments
Closed

[Bug]: Setting ticks marks on a single spine doesn't work properly #25117

WWakker opened this issue Jan 31, 2023 · 3 comments
Labels
Community support Users in need of help.

Comments

@WWakker
Copy link

WWakker commented Jan 31, 2023

Bug summary

When setting the tick length on the top spine only, it is also applied to the bottom spine, creating space between the bottom of the chart and the axis labels.

Code for reproduction

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(range(2020, 2025),
        range(-2, 3))

ax.spines['top'].set_position('zero')
ax.spines['bottom'].set_visible(False)
ax.tick_params(labelbottom=True, labeltop=False, bottom=False, top=True)
ax.spines['top'].axis.set_tick_params(length=10)
ax.set_xticks(range(2020, 2025))

plt.show()

Actual outcome

image

Expected outcome

image

Additional information

No response

Operating system

Windows

Matplotlib Version

3.3.4

Matplotlib Backend

TkAgg

Python version

3.6.13

Jupyter version

No response

Installation

pip

@jklymak
Copy link
Member

jklymak commented Jan 31, 2023

I don't think the tick parameters are customizable between the top and bottom spines; note that ax.spines['top'].axis is the same object as ax.spines['bottom'].axis.

If you want a different spine in the middle of your figure with no labels, you could try using ax.secondary_xaxis (https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.secondary_xaxis.html). It should be completely configurable independent of the main x-axis. The only issue is that I don't know that you can pin secondary_xaxis to a data value (eg. 0). versus a location on the axes (eg. 0.5)

@WWakker
Copy link
Author

WWakker commented Jan 31, 2023

Okay thanks a lot for clarifying. I could solve the problem completely like this:

import matplotlib.pyplot as plt


def get_location(ax, value, axis='x'):
    lb, ub = ax.get_ylim() if axis == 'y' else ax.get_xlim()
    assert lb <= value <= ub, f"value must be between {lb} and {ub}, found: {value}"
    return value - lb / (ub - lb)


fig, ax = plt.subplots()
ax.plot(range(2021, 2025),
        range(-1, 3))

ax.tick_params(labelbottom=True, bottom=False, top=False)
ax2 = ax.secondary_xaxis(location=get_location(ax=ax, value=0, axis='y'))
ax2.tick_params(labelbottom=False, direction='in', length=10)
ax.set_xticks(range(2021, 2025))

plt.show()

image

Closing the issue.

@jklymak
Copy link
Member

jklymak commented Jan 31, 2023

Slight follow up in #25119 - would be nice to be able to place the secondary axes in data co-ordinates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community support Users in need of help.
Projects
None yet
Development

No branches or pull requests

3 participants