Repository: pandas-dev/pandas
Pull request: BUG: fix custom xticks in bar() plotting function
- [x] closes #14119
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Problem statement:
unable to set xticks within bar() plotting function
#### Code Sample, a copy-pastable example if possible

In the code below:

``` python
pd.Series(range(10), index=range(10)).plot.bar(xticks=range(0, 11, 2))
```

`xticks` argument has no effect.  However, there's no such problem in line() plot.
#### Expected Output

Output plot is expected to have xticks defined by `xticks` argument, e.g. in the example above it should be set to [0, 2, 4, 6, 8, 10].
#### output of `pd.show_versions()`

commit: None
python: 2.7.12.final.0
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None

pandas: 0.18.1
nose: None
pip: 8.1.2
setuptools: 23.0.0
Cython: None
numpy: 1.11.1
scipy: 0.17.1
statsmodels: None
xarray: 0.8.1
IPython: 5.0.0
sphinx: None
patsy: None
dateutil: 2.5.3
pytz: 2016.4
blosc: None
bottleneck: None
tables: None
numexpr: None
matplotlib: 1.5.1
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
httplib2: None
apiclient: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.8
boto: None
pandas_datareader: None

Hints from issue discussion:
We'd need to decide what to do if `len(series)` isn't equal to `len(xticks)`, I assume matplotlib will just throw and error, which is probably fine.

Mind stepping through `tools/plotting.py` to see what's going on?

At first glance it doesn't look very straightforward. I'll look more closely a bit later.

Commit message: Fixing issue #14119

Patch to review:
diff --git a/doc/source/whatsnew/v0.25.2.rst b/doc/source/whatsnew/v0.25.2.rst
index 6974c7521a237..4f49f7d083520 100644
--- a/doc/source/whatsnew/v0.25.2.rst
+++ b/doc/source/whatsnew/v0.25.2.rst
@@ -69,7 +69,7 @@ I/O
 Plotting
 ^^^^^^^^
 
--
+- Fixed xticks in :core.py: `BarPlot._post_plot_logic` when setting a custom xticks
 -
 -
 
diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py
index 6ff3f28440303..81e9a488b6f15 100644
--- a/pandas/plotting/_matplotlib/core.py
+++ b/pandas/plotting/_matplotlib/core.py
@@ -1310,6 +1310,7 @@ def __init__(self, data, **kwargs):
         pos = kwargs.pop("position", 0.5)
         kwargs.setdefault("align", "center")
         self.tick_pos = np.arange(len(data))
+        self.custom_tick_pos = kwargs.pop("xticks", None)
 
         self.bottom = kwargs.pop("bottom", 0)
         self.left = kwargs.pop("left", 0)
@@ -1435,8 +1436,13 @@ def _post_plot_logic(self, ax, data):
 
     def _decorate_ticks(self, ax, name, ticklabels, start_edge, end_edge):
         ax.set_xlim((start_edge, end_edge))
-        ax.set_xticks(self.tick_pos)
-        ax.set_xticklabels(ticklabels)
+
+        if self.custom_tick_pos is not None:
+            ax.set_xticks(np.array(self.custom_tick_pos))
+        else:
+            ax.set_xticks(self.tick_pos)
+            ax.set_xticklabels(ticklabels)
+
         if name is not None and self.use_index:
             ax.set_xlabel(name)
 


Code review comments:
diff_hunk: @@ -1310,6 +1310,7 @@ def __init__(self, data, **kwargs):
         pos = kwargs.pop("position", 0.5)
         kwargs.setdefault("align", "center")
         self.tick_pos = np.arange(len(data))
+        self.custom_tick_pos = kwargs.pop("xticks", None)
path: pandas/plotting/_matplotlib/core.py
text: @user1:
It seems that `MPLPlot` calls this `self.x_ticks`. Can you try removing this and using `self.x_ticks` below?