如何将条形图居中以显示某列的差异?

时间:2017-08-26 21:23:13

标签: python matplotlib

如何使条形图居中以显示某列的差异?

我有以下条形图,用matplotlib完成:Bar plot

注意条形图真的很糟糕。确实可以正确看待每个酒吧之间的差异。所以我想要的是使用红色条作为y轴的原点。这样,其他栏会显示差异(blue_bar(i) - redbar)。

换句话说,我希望y轴上的红色条的值是图的y原点。

再一次,换句话说,红色条是我学术工作所获得的准确性。我想将其他文章的结果与 IN RELATION 进行比较,以便与我的比较。

我使用paint.net制作了以下图片来说明我想要的内容。 任何其他想法/建议都非常感谢。

enter image description here

附录:

我使用以下代码生成第一个图形:

import numpy as np
import random
from matplotlib import pyplot as plt

accuracies = [0.9630, 0.9597, 0.9563, 0.9533, 0.9527, 0.9480, 0.9477, 0.9472, 0.9472, 0.9466, 0.9452, 0.9452, 0.9442,
              0.9440, 0.9434, 0.9420, 0.9407, 0.9407, 0.9391, 0.9377, 0.9185, 0.9268]

sensitividades = [0.7680, 0.7200, 0.8173, 0.7569, 0.7406, 0.7354, 0.7746, 0.7344, 0.7067, 0.7410, 0.7370, 0.7321,
                  0.7357]

especificidades = [0.9827, 0.9733, 0.9816, 0.9807, 0.9789, 0.9724, 0.9764, 0.9801, 0.9751, 0.9521, 0.9487, 0.9694]

accuracies = [x * 100 for x in accuracies]

y = accuracies

N = len(y)
x = range(N)
width = 1 / 1.1
fig, ax = plt.subplots(1, 1)
ax.grid(zorder=0)

# Plot other articles
ax.bar(x, y, width, color="blue", zorder=3)

# Plot my work
ax.bar(x[len(x) - 1] + 1, 95.30, width, color="red", zorder=3)

plt.title('Accuracy of each article')
plt.xlabel('Article')
plt.ylabel('Accuracy')

plt.savefig('foo.png')
plt.show()

2 个答案:

答案 0 :(得分:3)

您可以将y限制设置为更接近有趣的值:

import numpy as np
import random
from matplotlib import pyplot as plt

accuracies = [0.9630, 0.9597, 0.9563, 0.9533, 0.9527, 0.9480, 0.9477, 0.9472, 0.9472, 0.9466, 0.9452, 0.9452, 0.9442,
              0.9440, 0.9434, 0.9420, 0.9407, 0.9407, 0.9391, 0.9377, 0.9185, 0.9268]

sensitividades = [0.7680, 0.7200, 0.8173, 0.7569, 0.7406, 0.7354, 0.7746, 0.7344, 0.7067, 0.7410, 0.7370, 0.7321,
                  0.7357]

especificidades = [0.9827, 0.9733, 0.9816, 0.9807, 0.9789, 0.9724, 0.9764, 0.9801, 0.9751, 0.9521, 0.9487, 0.9694]

accuracies = [x * 100 for x in accuracies]

my_acc = 95.30
y = accuracies

N = len(y)
x = range(N)
width = 1 / 1.1
fig, ax = plt.subplots(1, 1)
ax.grid(zorder=0)

# Plot other articles
ax.bar(x, y, width, color="blue", zorder=3)

# Plot my work
ax.bar(x[len(x) - 1] + 1, my_acc, width, color="red", zorder=3)

plt.title('Accuracy of each article')
plt.ylim(min(y) - 0.5, max(y) +0.5)
plt.xlabel('Article')
plt.ylabel('Accuracy')

plt.savefig('foo2.png')
plt.show()

reduced y range

或者你可以将它绘制在零附近,你的结果是新的原点(但是你必须指明你在图例或其他地方的某个位置移动了原点):

import numpy as np
import random
from matplotlib import pyplot as plt

accuracies = [0.9630, 0.9597, 0.9563, 0.9533, 0.9527, 0.9480, 0.9477, 0.9472, 0.9472, 0.9466, 0.9452, 0.9452, 0.9442,
              0.9440, 0.9434, 0.9420, 0.9407, 0.9407, 0.9391, 0.9377, 0.9185, 0.9268]

sensitividades = [0.7680, 0.7200, 0.8173, 0.7569, 0.7406, 0.7354, 0.7746, 0.7344, 0.7067, 0.7410, 0.7370, 0.7321,
                  0.7357]

especificidades = [0.9827, 0.9733, 0.9816, 0.9807, 0.9789, 0.9724, 0.9764, 0.9801, 0.9751, 0.9521, 0.9487, 0.9694]

accuracies = [x * 100 for x in accuracies]

my_acc = 95.30
y = np.asarray(accuracies) - my_acc

N = len(y)
x = range(N)
width = 1 / 1.1
fig, ax = plt.subplots(1, 1)
ax.grid(zorder=0)

# Plot other articles
bars = ax.bar(x, y, width, color="blue", zorder=3)

# Plot my work
# ax.bar(x[len(x) - 1] + 1, my_acc, width, color="red", zorder=3)

plt.title('Accuracy of each article')
plt.yticks([0, -0.3, -1.3, -2.3, -3.3, 0.7, 1.7], [95.30, 95, 94, 93, 92, 96, 97])
plt.xlabel('Article')
plt.ylabel('Accuracy')
plt.ylim(min(y) - 0.5, max(y) + 0.7)


def autolabel(rects):
    for i in range(len(rects)):
        rect = rects[i]
        height = rect.get_height()
        if (height >= 0):
            ax.text(rect.get_x() + rect.get_width()/2.,
            0.3 + height,'[{}]'.format( i), ha='center', va='bottom', 
            fontsize=7.5)
        if (height < 0):
            ax.text(rect.get_x() + rect.get_width()/2.,
            height - 0.3,'[{}]'.format( i), ha='center', va='bottom', 
            fontsize=7.5)

autolabel(bars)
plt.savefig('foo.png')
plt.show()

new y origin

当然,你自己的结果不会出现在第二个图中,因为它的高度为零。

答案 1 :(得分:2)

我实际上认为你现在表现出来的方式实际上是最好的 - 这意味着在粗略的水平上,准确性没有太大差异。

但是,如果要将红条的值设置为原点,请尝试以下操作:

...
plt.title('Accuracy of each article')
plt.xlabel('Article')
plt.ylabel('Accuracy')

plt.ylim(95.30) # Sets the value of the red bar as the origin.

plt.savefig('foo.png')
plt.show()

enter image description here

或许设置文章最低精度的最小值可能会使此图表更容易理解。

...
plt.title('Accuracy of each article')
plt.xlabel('Article')
plt.ylabel('Accuracy')

plt.ylim(min(accuracies), 100) # Sets the value of minimum accuracy as the origin and the max value as 100.

plt.savefig('foo.png')
plt.show()

enter image description here