Skip to content

BUG: axvspan breaks when using pandas .plot() wrapper #51795

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
2 of 3 tasks
DanielHabenicht opened this issue Mar 5, 2023 · 6 comments
Closed
2 of 3 tasks

BUG: axvspan breaks when using pandas .plot() wrapper #51795

DanielHabenicht opened this issue Mar 5, 2023 · 6 comments
Labels
Bug Needs Triage Issue that has not been reviewed by a pandas team member

Comments

@DanielHabenicht
Copy link

DanielHabenicht commented Mar 5, 2023

Pandas version checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of pandas.

  • I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

df = pd.read_csv("export.csv", index_col="Timestamp", parse_dates=True)

start = pd.Timestamp("2019-01-15 23:00:00+0000", tz="UTC")
end = pd.Timestamp("2019-02-01 09:50:00+0000", tz="UTC")
print(start)
print(df.index[0])
print(end)

fig, ax = plt.subplots()
ax.axvspan(
    start, # or df.index[0]
    end, # or df.index[-1]
    color="red",
    alpha=0.1,
    lw=0,
    zorder=1,
)

# Using the `ax.plot` method works
# ax.plot(df2.index, df2["n1"], color="black", alpha=0.2, linestyle="solid", zorder=3)

df.plot(ax=ax, alpha=0.2, linestyle="solid", zorder=3)

# Using `axvspan` before and after the plot actually works too
# Only using this axvspan method results in a blank graph
# ax.axvspan(
#     start,
#     end,
#     color="red",
#     alpha=0.1,
#     lw=0,
#     zorder=1,
# )

plt.show()

Issue Description

Using the wrapper functions somehow generates weird behaviour for plotting.
Interestingly only with the data I used here: export.csv

Using the axvspan before df.plot():
image

Using the axvspan after df.plot():
image

Expected Behavior

Using axvspan before and after df.plot or using the standard ax.plot(x,y) function:
image

Related

There was some weirdness reported before; #5092

Installed Versions

INSTALLED VERSIONS

commit : 2e218d1
python : 3.10.10.final.0
python-bits : 64
OS : Linux
OS-release : 5.15.90.1-microsoft-standard-WSL2
Version : #1 SMP Fri Jan 27 02:56:13 UTC 2023
machine : x86_64
processor :
byteorder : little
LC_ALL : None
LANG : C.UTF-8
LOCALE : en_US.UTF-8

pandas : 1.5.3
numpy : 1.24.2
pytz : 2022.7.1
dateutil : 2.8.2
setuptools : 67.4.0
pip : 23.0
Cython : None
pytest : 7.2.1
hypothesis : None
...
xlrd : None
xlwt : None
zstandard : None
tzdata : None

@DanielHabenicht DanielHabenicht added Bug Needs Triage Issue that has not been reviewed by a pandas team member labels Mar 5, 2023
@ritikBhandari
Copy link

Hi @DanielHabenicht ,

When I run the code, I got the same result as it was expected to show for using axvspan() after df.plot().
download

Regarding why the stuff works different when applied to different position is when you call df.plot(), it creates a new plot on the current figure with a new set of axes(). When we axvspan() after that, it is applied to the current set of axes which by default is the last set of axes created by the most recent plot command. So when you call axvspan() after df.plot(), it applies the shaded region to the plot that was just created by df.plot().

On the other hand, when you call axvspan() before it, the shaded region is created on the plot before df.plot() is called. So it is drawn behind the plot.

You can play around with zorder parameter to make sure it is shown in front of the plot.

@DanielHabenicht
Copy link
Author

DanielHabenicht commented Mar 7, 2023

Hi @ritikBhandari, thanks for taking the time to reproduce the issue.

I did try it with zorder, as you can see in my example. It did not change the result:

  • If I apply axvspan only before df.plot only the graph shows up

  • If I apply axvspan only after df.plot nothing shows up.

  • If I apply it at both positions or use ax.plot it works as expected.

So in short, you can't reproduce it? Then I will try to reproduce it on another machine.

One more question:
For df.plot(ax=ax) I was under the impression that it would reuse my supplied axis, because I don't see why it is supplied otherwise?

@ritikBhandari
Copy link

So I tried to reproduce the code and it is showing me the shades when I apply axvspan after df.plot. This issue is mostly because of the machine you are using I guess.

And regarding why it isn't applying shades when used before df.plot, it is because matplotlib by-default covers the first layer (which in our case is the shade) when it is covered by another layer(our actual plot). So that is the reason it doesn't work when applied before df.plot.

@DanielHabenicht
Copy link
Author

DanielHabenicht commented Mar 7, 2023

Alright, seems like I also can't reproduce the df.plot() => axvspan case on a different machine.

But I would still expect that:

ax.axvspan(start, end)
ax.plot(df.index, df["n1"], linestyle="solid", zorder=3)

behaves the same as:

ax.axvspan(start, end)
df.plot(ax=ax, linestyle="solid", zorder=3)

@azjps
Copy link

azjps commented Dec 26, 2023

I didn't reproduce the exact same issue but I'm fairly certain this is the same underlying issue as #52895; df.plot() & axvspan() look as expected after ignoring inferred_freq

@mroeschke
Copy link
Member

Closing as a similar issue to #52895

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Needs Triage Issue that has not been reviewed by a pandas team member
Projects
None yet
Development

No branches or pull requests

4 participants