pythonpandasxticks

Pandas barplot is setting xticks far to the right of data when using a subset of a dataset


I'm trying to make 2 separate bar plots, one of which is a subset of the other. I can set the xticks of the full dataset just fine and get the result I'm expecting, but when I set the xticks of the subset, they populate way to the right of the data in the graph.

Here is an example of what I'm doing currently that isn't working:

exRange = list(range(0,100))
fullTicks = list(range(0,100, 10))
filterTicks = list(range(15,30,5))

exDf = pd.DataFrame(exRange, exRange)
filtered = exDf[15:30]

exDf.plot.bar(xticks=fullTicks)
filtered.plot.bar(xticks=filterTicks)

This gives me two plots: Full dataset plot Subset dataset plot

In the subset, it acts like the all the data has been shifted to start at 0 and go up to 15, rather than 15-29 like I expected, which bumps my xticks to the right of the actual data. But when I remove the xtick argument I can see that the x-axis labels the bar 15-29 like I expected. In my actual dataset I have many more than 15 rows, so just removing the xticks argument isn't an option, it isn't readable.

So far, I've tried changing to a Seaborn bar plot, using pd.to_numeric to make sure my x-column is all ints to match the xticks, and setting both the x-column and xticks to strings.

Am I fundamentally misunderstanding something about the way that plot.bar works? Plot by itself gives me the answer I'm expecting, so I'm assuming it's a lack of understanding on my end.

Thanks in advance for any help!


Solution

  • This is because pandas makes the assumption that your bar-plot values are always categorical. You can use matplotlib to make this chart:

    import pandas as pd
    from matplotlib import pyplot as plt
    exRange = list(range(0,100))
    fullTicks = list(range(0,100, 10))
    filterTicks = list(range(15,30,5))
    
    exDf = pd.DataFrame(exRange, exRange)
    filtered = exDf[15:30]
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
    
    ax1.bar(exDf.index, exDf[0])
    ax1.set_xticks(fullTicks)
    ax1.set_title('Full Data')
    
    ax2.bar(filtered.index, filtered[0])
    ax2.set_xticks(filterTicks)
    ax2.set_title('Filtered Data')
    
    plt.show()
    

    enter image description here