How to center the bar plot to show the difference of a certain column?

244
August 27, 2017, at 10:48 AM

How to center the bar plot to show the difference of a certain column?

I have the following bar plot, done with matplotlib :

Note how the barplot is really bad. The difference between each bar cant really be seen properly. So what I want, is to use the red bar as the origin in the y-axis. That way, the other bars would show the difference (blue_bar(i) - redbar).

In other words, I want the value of the red bar in the y-axis to be the y-origin of the plot.

Again, in another words, the red bar is the accuracy obtained by my academic work. I want to plot the other article results compared/ IN RELATION to mine.

I made the following picture using paint.net to illustrate what I want. Any other ideas/suggestions are really appreciated.

Appendix :

I used the following code to produce the first graphic :

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

You could either set the y limits closer to the interesting values:

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

Or you could plot it around zero, with your result being the new origin (but you will have to indicate by how much you shifted the origin somewhere in the legend or somewhere else):

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

Of course, your own result would not appear in the second plot, since it would have height zero.

Answer 2

I actually think the way you have it represented now is actually best -- meaning there isn't a huge difference in accuracy on a cursory level.

However, if you want to set the value of the red bar as the origin, try this:

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

Perhaps setting the minimum value of lowest accuracy of the article might make this graph more digestible.

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

Rent Charter Buses Company
READ ALSO
Unable to log messages while running a Flask app

Unable to log messages while running a Flask app

I am trying to tie Flask's logger to a FileHandler, so I can save custom log messages to a fileAnytime I try to log a message when a POST requests hits foo, nothing happens, at all

285
Message type websocket gdax (coinbase)

Message type websocket gdax (coinbase)

I am interested in getting real-time data using the Gdax (Coinbase) WebSocketI'm a total noob so I am inspecting the example Gdax posted in their documentation:

554
Extracting numbers from the next sibling&#39;s text

Extracting numbers from the next sibling's text

I would like to assign each number to the suitable tag in python27

258
Would like to check if user has account on connecting - Python/Flask

Would like to check if user has account on connecting - Python/Flask

I was wondering how I would go about implementing a feature to my practice blog that if its the users first time connecting and they go to the index, it would redirect them to the register page or if they have an account and are not logged in, it would redirect...

281