Reputation: 21981
I have the foll. dataframe:
Version A2011 v1.0h
Decade
1510 - 1500 -3.553251 -0.346051
1520 - 1510 -2.797978 -0.356409
1530 - 1520 -2.194027 -0.358922
1540 - 1530 -1.709211 -0.329759
1550 - 1540 -1.354583 -0.308463
1560 - 1550 -1.062436 -0.305522
1570 - 1560 -0.821615 -0.293803
1580 - 1570 -0.620067 -0.279270
1590 - 1580 -0.465902 -0.271717
1600 - 1590 -0.341307 -0.289985
1610 - 1600 -0.365580 -0.491428
1620 - 1610 -0.329492 -0.532413
1630 - 1620 -0.299107 -0.568895
1640 - 1630 -0.283209 -0.591281
1650 - 1640 -0.267895 -0.595867
1660 - 1650 -0.250805 -0.593352
1670 - 1660 -0.240772 -0.539465
1680 - 1670 -0.234985 -0.514080
1690 - 1680 -0.230892 -0.497424
1700 - 1690 -0.229585 -0.484620
1710 - 1700 -0.853362 -0.892739
1720 - 1710 -0.738257 -1.017681
1730 - 1720 -0.660543 -0.966818
1740 - 1730 -1.331018 -1.171711
1750 - 1740 -1.271687 -1.541482
1760 - 1750 -1.023931 -1.559551
1770 - 1760 -1.089076 -1.757628
1780 - 1770 -1.965483 -2.404880
1790 - 1780 -1.579474 -2.167510
1800 - 1790 -1.740528 -2.023357
1810 - 1800 -2.237945 -2.804366
1820 - 1810 -2.744933 -2.379714
1830 - 1820 -3.706726 -3.717356
1840 - 1830 -4.680707 -4.048362
1850 - 1840 -5.836515 -4.660951
1860 - 1850 -7.141815 -4.919932
1870 - 1860 -5.847633 -2.972652
1880 - 1870 -9.280493 -6.146244
1890 - 1880 -8.815674 -6.689340
1900 - 1890 -9.548756 -8.893766
1910 - 1900 -10.596151 -10.115838
1920 - 1910 -12.002151 -10.492217
1930 - 1920 -12.524735 -11.155891
1940 - 1930 -13.945205 -14.295251
1950 - 1940 -13.877164 -13.609756
1960 - 1950 -20.660728 -17.546248
1970 - 1960 -14.495609 -15.537517
1980 - 1970 -14.865093 -13.292412
1990 - 1980 -16.254918 -13.626304
2000 - 1990 -12.212572 -8.392916
and I plot it so:
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
ax = df.plot()
# major ticks every 5, minor ticks every 1
ax.xaxis.set_major_locator(MaxNLocator(11))
ax.grid(which='minor', alpha=0.2)
ax.grid(which='major', alpha=0.5)
ax.legend().set_visible(False)
plt.xticks(rotation=75)
plt.tight_layout()
plt.show()
Resulting figure looks like this:
How do I fix the number of major and minor ticks so that there are at least 10 major ticks, and user-specified number of minor ticks between major ticks?
Upvotes: 1
Views: 1446
Reputation: 35094
From a bit of looking around it seems that pandas doesn't play well with locators. It seems that the preferred method of setting ticklabels is automatic. The problem seems to be that the implicit coupling of data vs index, used when automatically setting the tick labels, gets mixed up with a different number of tick labels to be set.
It feels like there should be a better aproach (I don't have much experience with pandas), but in the mean time you can roll your own tick labels using a major formatter. My experience anyway is that df.plot()
is convenient, but if you want to be sure, you should use matplotlib directly.
The key trick is to set the major formatter of the x axis using a semi-documented IndexFormatter
, the labels of which come from the index
of the dataframe:
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator,IndexFormatter
ax = df.plot()
ax.xaxis.set_major_locator(MaxNLocator(11))
ax.xaxis.set_major_formatter(IndexFormatter(df.index)) # <-- new here
ax.grid(which='minor', alpha=0.2)
ax.grid(which='major', alpha=0.5)
ax.legend().set_visible(False)
plt.xticks(rotation=75)
plt.tight_layout()
plt.show()
And the reason your minor ticks are missing is this:
>>> ax.xaxis.get_minor_locator()
<matplotlib.ticker.NullLocator at 0x7faf53d0e1d0>
The default locator for minor ticks is a NullLocator
, which in effect disables minor ticks, which in turn leads to a distinct lack of minor grid lines. You should choose and set an appropriate Locator
for the minor ticks, and everything should work then (in other words, I'm not sure if there's an easy way to specify the number of minor grids in terms of the major ones).
Upvotes: 1