I'm new to using Matplotlib. I'm trying to build a chart where values can also be negative. Using the generic graph from matplotlib
import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt
objects = ('Python', 'C++', 'Java', 'Perl', 'Scala', 'Lisp')
y_pos = np.arange(len(objects))
performance = [10,8,6,-4,2,1]
plt.bar(y_pos, performance, align='center', alpha=0.5)
plt.xticks(y_pos, objects)
plt.ylabel('Usage')
plt.title('Programming language usage')
plt.show()
This produces
However, I would like to use x-axis as y=0 line instead of having separate y=0. So for any negative values, it would appear below x-axis and for positive values, it will appear above x-axis.
It would somehow look like this.
I've managed to get rid of the surrounding lines and values on y-axis. Need to know how to make the x-axis the y=0 line.
Any help would be appreciated.
Thank you so much in advance.
From here it's reasonably straightforward by accessing the axes object and modifying the spines
, you just have to expose the Axes
object first with the plt.gca()
method.
The downside here is that getting the xticklabels how you've put them is a bit trickier, but is just a case of placing the relevant text on the Axes
and then repeating that for the xlabel
. You could always try using the labelpad
argument for plt.xlabel()
but I've not really played much with that.
import matplotlib.pyplot as plt
plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt
objects = ('Python', 'C++', 'Java', 'Perl', 'Scala', 'Lisp')
y_pos = np.arange(len(objects))
performance = [10,8,6,-4,2,1]
plt.bar(y_pos, performance, align='center', alpha=0.5)
# Get the axes object
ax = plt.gca()
# remove the existing ticklabels
ax.set_xticklabels([])
# remove the extra tick on the negative bar
ax.set_xticks([idx for (idx, x) in enumerate(performance) if x > 0])
ax.spines["bottom"].set_position(("data", 0))
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
# placing each of the x-axis labels individually
label_offset = 0.5
for language, (x_position, y_position) in zip(objects, enumerate(performance)):
if y_position > 0:
label_y = -label_offset
else:
label_y = y_position - label_offset
ax.text(x_position, label_y, language, ha="center", va="top")
# Placing the x-axis label, note the transformation into `Axes` co-ordinates
# previously data co-ordinates for the x ticklabels
ax.text(0.5, -0.05, "Usage", ha="center", va="top", transform=ax.transAxes)
plt.show()
Result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With