kingmakerking
kingmakerking

Reputation: 2089

Matplotlib horizontal bar graph with x-axis label along y-axis

I have been using Pyasciigraph module as per the following snippet

thresholds = {
        int(mean): Gre, int(mean * 2): Yel, int(mean * 3): Red,
    }
    data = hcolor(chart, thresholds)

graph = Pyasciigraph(
            separator_length=4,
            multivalue=False,
            human_readable='si',
        )

for line in graph.graph(title, data):
    print(line)
    print("")

to draw a horizontal bar graph as follows (The y-axis label is not visible in the screenshot below):

Bar graph using Pyasciigraph :

Now, I am trying to plot the same using matplotlib for the same data, and my sample code is:

import collections
import matplotlib.pyplot as plt

D = [(u'00:00', 1), (u'01:00', 1), (u'02:00', 0), (u'03:00', 0), (u'04:00', 0), (u'05:00', 0), (u'06:00', 1), (u'07:00', 7), (u'08:00', 3), (u'09:00', 2), (u'10:00', 6), (u'11:00', 2), (u'12:00', 4), (u'13:00', 4), (u'14:00', 1), (u'15:00', 6), (u'16:00', 3), (u'17:00', 2), (u'18:00', 1), (u'19:00', 1), (u'20:00', 0), (u'21:00', 2), (u'22:00', 2), (u'23:00', 1)]
D2 = dict(D)
od2 = collections.OrderedDict(sorted(D2.items(), reverse=True))

plt.barh(range(len(od2)), od2.values(), align='center')
plt.yticks(range(len(od2)), od2.keys())
plt.gca().axes.get_xaxis().set_ticks([])
plt.show()

which gives raise to the following graph: enter image description here

Here is what I am missing in this graph compared to the one drawn using Pyasciigraph:

  1. The x-axis values (labels) are on the right side of y-axis.
  2. As it is shown in the Pyasciigraph, I could define treshold, change of colors for specific range of x-value.

The closest answer on stackoverflow related to mine is this, but it didn't help up.

Any suggestion, tips, help would be much appreciated.

Upvotes: 0

Views: 2104

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339230

In order to show the bar values on the right side of the plot, you may use a twin axes and set its labels to the values from the dictionary.

In order to produce thresholded bars, you can plot several bar plots on top of each other where each time the values are truncated to a threshold.

import collections
import matplotlib.pyplot as plt

D = [(u'00:00', 1), (u'01:00', 1), (u'02:00', 0), (u'03:00', 0), (u'04:00', 0), 
     (u'05:00', 0), (u'06:00', 1), (u'07:00', 7), (u'08:00', 3), (u'09:00', 2), 
     (u'10:00', 6), (u'11:00', 2), (u'12:00', 4), (u'13:00', 4), (u'14:00', 1), 
     (u'15:00', 6), (u'16:00', 3), (u'17:00', 2), (u'18:00', 1), (u'19:00', 1), 
     (u'20:00', 0), (u'21:00', 2), (u'22:00', 2), (u'23:00', 1)]
D2 = dict(D)
od = collections.OrderedDict(sorted(D2.items(), reverse=True))

fig, ax = plt.subplots()
ax.barh(range(len(od)), od.values(), align='center')

thr = lambda l, t:  [v if (v <= t) else t for v in l ]

ax.barh(range(len(od)), thr(od.values(),4), align='center')
ax.barh(range(len(od)), thr(od.values(),2), align='center')

ax.set_yticks(range(len(od)))
ax.set_yticklabels(od.keys())
ax.set_xticks([])

ax2 = ax.twinx()
ax2.set_ylim(ax.get_ylim())
ax2.set_yticks(range(len(od)))
ax2.set_yticklabels(od.values())

plt.show()

enter image description here

Upvotes: 1

Related Questions