Repository navigation
Closed
Labels
Difficulty: Mediumhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issueshttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues🌱 Good first issueOpen a pull request against these issues if there are no active ones!Open a pull request against these issues if there are no active ones!
Milestone
Description
Bug summary
For Axes.vlines(), when I want to use axes coordinate for ymin / ymax, as suggested in blended transformation, ymin is incorrectly treated as data coordinate.
Axes.hlines() has a similar problem with xmin.
Code for reproduction
# Sample derived from
# https://matplotlib.org/3.5.0/gallery/lines_bars_and_markers/vline_hline_demo.html#sphx-glr-gallery-lines-bars-and-markers-vline-hline-demo-py
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
print('matplotlib', matplotlib.__version__)
t = np.arange(5.0, 10.0, 0.1)
s = np.exp(-t) + np.sin(2 * np.pi * t) + 10
vax = plt.figure(figsize=(12, 6)).gca()
vax.plot(t, s, '^')
# By using ``transform=vax.get_xaxis_transform()`` the y coordinates are scaled
# such that 0 maps to the bottom of the axes and 1 to the top.
vax.vlines([6, 7], ymin=0, ymax=0.15, transform=vax.get_xaxis_transform(), colors='r')
# if I use axvline() instead, it correctly treats ymin as axes coordinate.
# vax.axvline(6, ymin=0, ymax=0.15, c='r')
# vax.axvline(7, ymin=0, ymax=0.15, c='r')
vax.set_xlabel('time (s)')
vax.set_title('Vertical lines demo');Actual outcome
One can see that while ymax is applied correctly (about 15% of the y-axis), ymin is applied incorrectly. ymin is treated as data coordinate, incorrectly stretching the y-axis.
Expected outcome
The expected outcome can be obtained using multiple axvline() instead of vlines():
vax.axvline(6, ymin=0, ymax=0.15, c='r')
vax.axvline(7, ymin=0, ymax=0.15, c='r')Additional information
I've encountered the problem in earlier versions. I cannot recall it ever works correctly.
Axes.hlines() has a similar problem with xmin.
One can add the following to the example codes above to test it:
# axes.hlines() has similar problem.
vax.hlines([9, 9,5], xmin=0, xmax=0.2, transform=vax.get_yaxis_transform(), colors='green')
# uses multiple axhline() call would work correctly
# vax.axhline(9, xmin=0, xmax=0.2, c='green')
# vax.axhline(9.5, xmin=0, xmax=0.2, c='green')Operating system
Windows
Matplotlib Version
3.5.2
Matplotlib Backend
module://matplotlib_inline.backend_inline
Python version
Python 3.9.10
Jupyter version
6.4.11
Installation
conda
Metadata
Metadata
Assignees
Labels
Difficulty: Mediumhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issueshttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues🌱 Good first issueOpen a pull request against these issues if there are no active ones!Open a pull request against these issues if there are no active ones!


Activity
[-][Bug]: axes vlines() / hlines() incorrectly use data coordinate as min when transform is applied[/-][+][Bug]: axes vlines() / hlines() incorrectly use data coordinate as min when blended transform is applied[/+]tacaswell commentedon Jun 1, 2022
Labeling this as a good first issue because there is no API design and this appears to be a clearly identified bug that should be fixed.
Labeling as medium difficulty as this is probably not a project someone new to Python should take on.
orionlee commentedon Jun 1, 2022
I suspect the problem lies with the scaling done at the end of
vlines()implementationmatplotlib/lib/matplotlib/axes/_axes.py
Lines 1142 to 1149 in 9765379
In the example scenario, the
minyandmaxyused in scaling are probably in axes coordinates, while the actual scaling inupdate_datalim()treat them as data coordinates.In contrast,
axvlines()has no such issue, because its scaling logic keeps y-axis scale unchanged.njj67229 commentedon Jul 14, 2022
Is anyone currently working on this issue? I have not done any open source contribution before and would be interested in giving it a stab as a first issue.
QuLogic commentedon Jul 20, 2022
I don't think anyone is working on this; feel free to take a stab at it.
Ailieena commentedon Aug 28, 2022
Hi, I'm new to open source and wanted to take a look at this issue.
I looked at the code and I'm not fully convinced that the current behavior is incorrect. The description of
vlinesfunction suggests that it should plot "vertical lines at each x from ymin to ymax.".It seems to me that
vlinesusingyminandymaxas coordinates is the expected outcome, am I wrong?story645 commentedon Aug 28, 2022
Forgive me if I'm misinterpreting your question, but the issue is that this function supports multiple coordinate systems and the original poster is trying to plot the vlines in the axes coordinate system. The axes coordinates are independent of the data coordinates and are fixed to the displayed axes:
In the expected image provided by the original poster, 0 in axes coordinates is the bottom of the displayed axes, which is supposed to be more or less at the same place as the data 9.

The bug is that instead of plotting the bottom of the line in axes coordinates (so at around data 9), it is plotting the line at 0 in data coordinates, which in turn is changing the axes to produce the incorrect example.
Ailieena commentedon Aug 28, 2022
Thank you for the explanation, I understand now. I'll look into it more.