Kernel
Kernel

Reputation: 709

The matplotlib ticker FuncFormatter

I am trying to manually set the ticker for a bar plot. I am using the FunFormatter function. Yet, I found that the behavior of the FunFormmater is too strange. For X-axis range from 0 to 91, I found that the FunFormmater returns the following ... Any idea how does it work. Here is the link for the data file Thanks in advance

-10.0 0.0 10.0 20.0 30.0 40.0 50.0 60.0 70.0 80.0 90.0 100.0 28.805725806451605 38.374395161290316 41.22463709677419 47.128709677419344 48.55383064516128 49.36818548387095 51.20048387096774 52.42201612903225 53.439959677419345 53.439959677419345 53.03278225806451 53.643548387096764 56.08661290322579 59.75120967741935 64.63733870967741 70.54141129032257 76.85266129032257 83.16391129032257 95.58282258064514

import numpy as np
import matplotlib.pyplot as plt
import pandas as p
import matplotlib.mlab as m
import matplotlib
import matplotlib.ticker as ticker

file1=np.load('numofdays.npz')
fig,axes=plt.subplots(ncols=1)
ax=axes
x=np.arange(len(file1['arr_0']))
y=np.array(file1['arr_0'])
ax.bar(x,y)
mydates=p.DatetimeIndex(file1['arr_1'])

def mme(xx,pos=None):
    print(xx)
#    print(mydates[int(xx-9)].strftime('%Y-%m-%d'))
    return mydates[int(xx-9)].strftime('%Y-%m-%d')

ax.xaxis.set_major_locator(ticker.MultipleLocator(10))
ax.xaxis.set_major_formatter(ticker.FuncFormatter(mme))
fig.autofmt_xdate()

Upvotes: 2

Views: 3458

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339052

It's a bit dangerous to show only every tenth label for unequally spaced data, because you don't know what happens in between.

However to get your script running, you will of course need to make sure the position xx is a valid index of the array. E.g. the position 100 is not valid, because your array only has 92 elements. To this end you may just introduce a condition.

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

import matplotlib.ticker as ticker

file1=np.load('data/numofdays.npz')

fig,ax=plt.subplots(ncols=1)

x=np.arange(len(file1['arr_0']))
y=np.array(file1['arr_0'])
ax.bar(x,y)
mydates=p.DatetimeIndex(file1['arr_1'])

def mme(xx,pos=None):
    if int(xx) in x:
        return mydates[int(xx)].strftime('%Y-%m-%d')
    else:
        return ""

ax.xaxis.set_major_locator(ticker.MultipleLocator(10))
ax.xaxis.set_major_formatter(ticker.FuncFormatter(mme))
fig.autofmt_xdate()
plt.show()

enter image description here

As an alternative, I would definitely consider plotting the actual dates.

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

file1=np.load('data/numofdays.npz')

fig,ax=plt.subplots(ncols=1)

y=np.array(file1['arr_0'])

mydates = p.DatetimeIndex(file1['arr_1'])

ax.bar(mydates,y, width=60)

fig.autofmt_xdate()
plt.show()

enter image description here

Upvotes: 3

Related Questions