Skip to content
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

Using pandas.TimeSeries_DateFormatter in bar plot? #1918

Open
sinhrks opened this issue Sep 16, 2012 · 13 comments
Open

Using pandas.TimeSeries_DateFormatter in bar plot? #1918

sinhrks opened this issue Sep 16, 2012 · 13 comments

Comments

@sinhrks
Copy link
Member

sinhrks commented Sep 16, 2012

xref #5774

When time series is set as index, line plot uses the TimeSeries_DateFormatter for recognizable date formatting. However, bar plot use the FixedFormatter which outputs the datetime as it is. Can bar plot also use the DateFormatter?

In [1]: from pandas import *
In [2]: from numpy.random import *
In [3]: ts = Series(randn(100), index=date_range('1/1/2000', periods=100))
In [4]: df = DataFrame(randn(100, 4), index=ts.index, columns=['A', 'B', 'C', 'D'])
In [5]: df = df.cumsum()

In [7]: a = df.plot(kind='bar')
In [9]: a.get_xaxis().get_major_formatter()
Out[9]: <matplotlib.ticker.FixedFormatter instance at 0x108700f38>

In [11]: a = df.plot()
In [12]: a.get_xaxis().get_major_formatter()
Out[12]: <pandas.tseries.converter.TimeSeries_DateFormatter instance at 0x10877ccf8>
@datapythonista
Copy link
Member

Just in case it's useful, I found a bug that looks related to this issue to me. This code from an ipython notebook shows the problem:

%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib
ts = pd.Series(np.random.randn(100), index=pd.date_range('1/1/2000', periods=100))
ax = ts.plot(kind='bar')
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m %d %Y'))

The first time it's executed it shows this warning, and the plot does not show:

~/.pydata/lib/python2.7/site-packages/IPython/core/formatters.py:239: FormatterWarning: Exception in image/png formatter: DateFormatter found a value of x=0, which is an illegal date. This usually occurs because you have not informed the axis that it is plotting dates, eg with ax.xaxis_date()
FormatterWarning,

Next executions the warning does not appear, neither the plot.

Some things that makes the plot appear:

  • Removing the kind='bar'
  • Removing the last line of code, where the formatter is set
  • Changing the DateFormatter by another like the FormatStrFormatter
  • Using plt.bar instead of pandas Series plot method

Hope this helps

@jorisvandenbossche
Copy link
Member

Related with #8803

@ehsteve
Copy link

ehsteve commented Oct 13, 2015

I've just run into this problem as well. Would very much appreciate a fix.

@tharibo
Copy link

tharibo commented Apr 26, 2016

Same problem here. Is there a workaround?

@pwaller
Copy link
Contributor

pwaller commented Apr 26, 2016

Funny, I subscribed to this issue yesterday and someone replies to it! I too have had lots of problems with plot(kind="bar") with time series data. A lot of things are screwed up. The x-axis dates aren't shown correctly, ax.twinx() doesn't work properly. I've resorted to using plt.bar(df.index, df.values) with much greater success.

@pwaller
Copy link
Contributor

pwaller commented Apr 25, 2017

Just hit this again. Can't figure out how to get the bar plot to show dates sensibly at all, it's showing a complete timestamp "%d/%m/%Y %H:%M:%S" for something which is a 2-month granularity. I just want it to show 04/2017, but the obvious ax.xaxis.set_major_formatter(plt.DateFormatter('%m/%Y')) does not work.

@pwaller
Copy link
Contributor

pwaller commented Apr 25, 2017

Exception for reference:

/home/pwaller/.local/lib/python3.5/site-packages/matplotlib/dates.py in __call__(self, x, pos)
    460     def __call__(self, x, pos=0):
    461         if x == 0:
--> 462             raise ValueError('DateFormatter found a value of x=0, which is '
    463                              'an illegal date.  This usually occurs because '
    464                              'you have not informed the axis that it is '

ValueError: DateFormatter found a value of x=0, which is an illegal date.  This usually occurs because you have not informed the axis that it is plotting dates, e.g., with ax.xaxis_date()

@pwaller
Copy link
Contributor

pwaller commented Apr 25, 2017

I found a workaround, by applying this at the end:

In this case, d is the DataFrame I'm plotting, and d.index is the DatetimeIndex.

plt.gca().xaxis.set_major_formatter(plt.FixedFormatter(d.index.to_series().dt.strftime("%b %Y")))

@shankari
Copy link

#1918 (comment) works!
Just FYI, if you have stored the axis for the plot already (as in #1918 (comment)), you can also do

ax.xaxis.set_major_formatter(plt.FixedFormatter(ts.index.to_series().dt.strftime("%d %b %Y")))

@pwaller
Copy link
Contributor

pwaller commented Jul 31, 2017

I'm not a huge fan of the workaround and hit this quite frequently still. It also doesn't produce x-axis labels which are as good a data.plot() does, because the latter does Year labels on a separate row than Month labels, and I don't know how to achieve the same effect. I'd love for bar chars to be able to display time series data in the same way that line plots do, sometimes it is a less misleading way to present the data.

@jfuentescpp
Copy link

workaround still saving the day!

How to set xlim with this solution? Already tried
ax.set_xlim([datetime(2018, 6, 1, 0,0), datetime(2019, 3, 1, 0,0)])
ax.set_xlim(pd.Timestamp() ...

@poke1024

This comment was marked as off-topic.

@mroeschke mroeschke removed this from the Someday milestone Oct 13, 2022
@Compro-Prasad
Copy link
Contributor

Compro-Prasad commented Mar 10, 2024

xref #5774

When time series is set as index, line plot uses the TimeSeries_DateFormatter for recognizable date formatting. However, bar plot use the FixedFormatter which outputs the datetime as it is. Can bar plot also use the DateFormatter?

In [1]: from pandas import *
In [2]: from numpy.random import *
In [3]: ts = Series(randn(100), index=date_range('1/1/2000', periods=100))
In [4]: df = DataFrame(randn(100, 4), index=ts.index, columns=['A', 'B', 'C', 'D'])
In [5]: df = df.cumsum()

In [7]: a = df.plot(kind='bar')
In [9]: a.get_xaxis().get_major_formatter()
Out[9]: <matplotlib.ticker.FixedFormatter instance at 0x108700f38>

In [11]: a = df.plot()
In [12]: a.get_xaxis().get_major_formatter()
Out[12]: <pandas.tseries.converter.TimeSeries_DateFormatter instance at 0x10877ccf8>

Screenshots for reference:
image
image

Just in case it's useful, I found a bug that looks related to this issue to me. This code from an ipython notebook shows the problem:

%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib
ts = pd.Series(np.random.randn(100), index=pd.date_range('1/1/2000', periods=100))
ax = ts.plot(kind='bar')
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%m %d %Y'))

The first time it's executed it shows this warning, and the plot does not show:

~/.pydata/lib/python2.7/site-packages/IPython/core/formatters.py:239: FormatterWarning: Exception in image/png formatter: DateFormatter found a value of x=0, which is an illegal date. This usually occurs because you have not informed the axis that it is plotting dates, eg with ax.xaxis_date()
FormatterWarning,

Next executions the warning does not appear, neither the plot.

Some things that makes the plot appear:

* Removing the `kind='bar'`

* Removing the last line of code, where the formatter is set

* Changing the DateFormatter by another like the FormatStrFormatter

* Using `plt.bar` instead of pandas Series `plot` method

Hope this helps

The above mentioned warning doesn't show up anymore:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests