Zenshu
Zenshu

Reputation: 13

Issues with ylim when combining pandas plots

I am having an issue with the scale of my y-axis when combining an area plot with a line plot in Pandas.

here is an example to illustrate it:

df= pd.DataFrame(abs(np.random.randn(50, 4)), columns=list('ABCD'))
for col in ["A", "B", "C"]:
    df[col]=df[col]*1000
df["D"]=df["D"]*5000

fig, ax = plt.subplots(figsize=(28, 10))
ax=df[["A", "B", "C"]].plot.area(ax=ax)
ax=df["D"].plot.line(ax=ax, color='red')
print(ax.get_ylim())
ax.margins(0, 0)
ax.legend_.remove()
plt.show()

result of ax.get_ylim() is: (0.0, 4917.985892131057)

and the graph looks like:

enter image description here

As you can see the graph is cropped at the top and I am missing information regarding the plot D. The expected result would be:

enter image description here

and in that case get_ylim() is (-613.14902407399052, 16197.881540891121).

I have obtained this second graph by inputting manually the ylim.

Could you let me know what am I doing wrong? Why could I not get the y_lim from my "D" plot in my example?

Many thanks in advance!

Upvotes: 1

Views: 668

Answers (3)

akilat90
akilat90

Reputation: 5696

You can manually set the y axis limits using ax.set_ylim(). But I think the best way wouyld be to use ax.autoscale() as suggested by @ImportanceOfBeingErnest

fig, ax = plt.subplots(figsize=(28, 10))
ax.set_ylim(0, df.max().max()) # setting the upper y_limit to the maximum value in the dataframe
df[["A", "B", "C"]].plot.area(ax=ax)
df["D"].plot.line(ax=ax, color='red')

plt.show()

enter image description here

Upvotes: 0

jeffery_the_wind
jeffery_the_wind

Reputation: 18158

I think this is becuase the limits are set initally by the first set of data plotted. Try switching them around:

ax=df["D"].plot.line(ax=ax, color='red')
ax=df[["A", "B", "C"]].plot.area(ax=ax)

But again this depends on the data, it will only work if "D" is always bigger than the others. You could add a line to automatically update the ylim like this:

ax.set_ylim(top=df.values.max())

Upvotes: 0

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339102

You would want to autoscale the graph after adding all plots to it.

ax.autoscale()

In order for the bottom of the data sitting tight to zero in y direction you can use ax.set_ylim(0,None) and for x direction ax.margins(x=0).

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df= pd.DataFrame(abs(np.random.randn(50, 4)), columns=list('ABCD'))
for col in ["A", "B", "C"]:
    df[col]=df[col]*1000
df["D"]=df["D"]*5000

fig, ax = plt.subplots()
ax=df[["A", "B", "C"]].plot.area(ax=ax)
ax=df["D"].plot.line(ax=ax, color='red')

ax.get_legend().remove()

ax.autoscale()
ax.set_ylim(0,None)
ax.margins(x=0)

plt.show()

enter image description here

Upvotes: 1

Related Questions