Отрицательные значения гистограммы Matplotlib ниже оси X - PullRequest
2 голосов
/ 04 марта 2020

Я новичок в использовании Matplotlib. Я пытаюсь построить график, где значения также могут быть отрицательными. Использование обобщенного графика c из 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()

Это производит

enter image description here

Однако я хотел бы использовать x- ось как линия y = 0 вместо того, чтобы иметь отдельную y = 0. Таким образом, для любых отрицательных значений он будет отображаться ниже оси x, а для положительных значений - выше оси x.

Это будет выглядеть как-то так.

enter image description here

Мне удалось избавиться от окружающих линий и значений на оси Y. Нужно знать, как сделать ось х линией y = 0.

Любая помощь будет оценена.

Заранее большое спасибо.

1 Ответ

3 голосов
/ 04 марта 2020

Начиная с здесь это довольно просто, для доступа к объекту осей и изменения spines, вам просто нужно сначала выставить объект Axes с помощью метода plt.gca().

Недостатком здесь является то, что получить xticklabels, как вы их поместили, немного сложнее, но это всего лишь случай размещения соответствующего текста на Axes с последующим повторением этого для xlabel. Вы всегда можете попробовать использовать аргумент labelpad для plt.xlabel(), но я не особо с этим справляюсь.

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()

Результат:

bar plot output from code above

...