1

I have a chart, created in pandas, where I've set the y-axis to range from -100 to -100.

Is there an easy way to have the x-axis cross the y-axis at y=0, instead of crossing at y=-100 (or, how to display the x-axis at the vertical center, instead of at the bottom of the chart)

Solutions I've seen seem to use subplots or spines, which seem to be overly complicated for my purpose. I am looking for something more integrated with pandas, like passing the ylim or style argument)

Sample code:

from pandas import Series
s=Series([-25,0,70])
s.plot(ylim=(-100,100))

chart with x-axis at the bottom

Rabarberski
  • 23,854
  • 21
  • 74
  • 96
  • can you post your code please, it just makes it easier to visualize your issue even though it is clear what you want – Ryan Saxe May 15 '13 at 18:33
  • You can manually draw a line in the middle of the plot: http://stackoverflow.com/questions/5394527/matplotlib-how-to-draw-an-axis-in-the-middle-of-the-figure. But it seems like matplotlib does not have a command to send the xaxis.tick to the middle of the plot. (There is `ax.xaxis.tick_bottom` and `ax.xaxis.tick_top`, but not middle) – joon May 15 '13 at 18:40
  • As far as I know there is no such feature available in `pandas`, as the plotting capabilities of `pandas` are very limited compared to `matplotlib`. Also, if you want to have the ticklabels/tickmarks of the x-axis connected to the "middle axis" (also while panning/zooming), then it's easiest to insert an extra spine; take a look at [`mpl_toolkits.axisartist`](http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html#axisartist) for some examples of this. – sodd May 15 '13 at 20:54
  • That example you link to is probably the easiest way. – tacaswell May 16 '13 at 01:30

1 Answers1

1

The solution I have so far is indeed using subplots:

from pandas import Series
s=Series([-25,0,70])

import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_ylabel('percentage')
ax.spines['bottom'].set_position('zero')       # x-axis where y=0
#ax.spines['bottom'].set_position('center')     # x-axis at center (not necessarily y=0)
#ax.spines['bottom'].set_position(('data', 50)) # x-axis where y=50
ax.spines['top'].set_color('none')             # hide top axis
ax.spines['right'].set_color('none')           # hide right axis

s.plot(ylim=(-100,100))

chart with centered x-axis

Not sure why the gridline at the bottom is not shown, but not an issue for me

Rabarberski
  • 23,854
  • 21
  • 74
  • 96
  • 1
    When I run your code, the gridline at the bottom is actually shown (matplotlib 1.2.1). In this case I would recommend to use `ax.spines['bottom'].set_position('zero')` rather than `ax.spines['bottom'].set_position('center')`, as the latter places the spine in the center of the `Axes`, not necessarily at y=0, meaning it moves relative to the y-axis while panning/zooming. These are analogous only when the y-limits are symmetric about y=0. Also, you can remove the "floating" tickmarks at the top and right with `ax.tick_params(top=False, right=False)` to get a cleaner look. – sodd May 16 '13 at 11:40
  • include the import of the `plt` namespace for completion of code example – mtadd May 16 '13 at 14:35