25

I use Python 2.7 and matplotlib. I have a *.txt data file :

0 14-11-2003
1 15-03-1999
12 04-12-2012
33 09-05-2007
44 16-08-1998
55 25-07-2001
76 31-12-2011
87 25-06-1993
118 16-02-1995
119 10-02-1981
145 03-05-2014

first column of my file (numbers) should be on axis Y in my bar chart, and the second column from my file (dates) should be on axis OX in my histogram. I only know how to read the file:

OX = []
OY = []

try :
    with open('data.txt', 'r') as openedFile :
        for line in openedFile :
            tab = line.split()
            OY.append(int(tab[0]))
            OX.append(str(tab[1]))
except IOError :
    print("IOError!")

I did read a matplotlib docs but it still doesn't help me. I would also like to add dates I read to my bar chart, to make it look like

this

Could someone please help me?

David Robinson
  • 77,383
  • 16
  • 167
  • 187
mazix
  • 2,540
  • 8
  • 39
  • 56

3 Answers3

30

You're talking about histograms, but this doesn't quite make sense. Histograms and bar charts are different things. An histogram would be a bar chart representing the sum of values per year, for example. Here, you just seem to be after bars.

Here is a complete example from your data that shows a bar of for each required value at each date:

import pylab as pl
import datetime

data = """0 14-11-2003
1 15-03-1999
12 04-12-2012
33 09-05-2007
44 16-08-1998
55 25-07-2001
76 31-12-2011
87 25-06-1993
118 16-02-1995
119 10-02-1981
145 03-05-2014"""

values = []
dates = []

for line in data.split("\n"):
    x, y = line.split()
    values.append(int(x))
    dates.append(datetime.datetime.strptime(y, "%d-%m-%Y").date())

fig = pl.figure()
ax = pl.subplot(111)
ax.bar(dates, values, width=100)
ax.xaxis_date()

You need to parse the date with strptime and set the x-axis to use dates (as described in this answer).

If you're not interested in having the x-axis show a linear time scale, but just want bars with labels, you can do this instead:

fig = pl.figure()
ax = pl.subplot(111)
ax.bar(range(len(dates)), values)

EDIT: Following comments, for all the ticks, and for them to be centred, pass the range to set_ticks (and move them by half the bar width):

fig = pl.figure()
ax = pl.subplot(111)
width=0.8
ax.bar(range(len(dates)), values, width=width)
ax.set_xticks(np.arange(len(dates)) + width/2)
ax.set_xticklabels(dates, rotation=90)
Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • that's great but is there a way to set the labels on axis x more vertically on the picture? It won't look good with lot of data on axis x. But thanks, I will definitely use your example:) – mazix Jul 23 '12 at 21:23
  • thanks :) just one more thing: how to set those date-labels just right under each bin? I tried with different rotation angle but it's not good enough: http://s6.ifotos.pl/img/chartpng_raqrsaq.png – mazix Jul 24 '12 at 20:33
  • 1
    @Xeoncross 1 row, 1 column, 1st position. [*pos is a three digit integer, where the first digit is the number of rows, the second the number of columns, and the third the index of the subplot. i.e. fig.add_subplot(235) is the same as fig.add_subplot(2, 3, 5). Note that all integers must be less than 10 for this form to work.*](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplot.html) (Essentially, there's only one subplot here, in position 1 out of 1 row/1 col.). – Bruno Apr 05 '19 at 12:22
24

This code will do what you're looking for. It's based on examples found here and here.

The autofmt_xdate() call is particularly useful for making the x-axis labels readable.

import numpy as np
from matplotlib import pyplot as plt

fig = plt.figure()

width = .35
ind = np.arange(len(OY))
plt.bar(ind, OY, width=width)
plt.xticks(ind + width / 2, OX)

fig.autofmt_xdate()

plt.savefig("figure.pdf")

enter image description here

fresskoma
  • 25,481
  • 10
  • 85
  • 128
David Robinson
  • 77,383
  • 16
  • 167
  • 187
3

First, what you are looking for is a column or bar diagram, not really a histogram. A histogram is made from a frequency distribution of a continuous variable that is separated into bins. Here you have a column against separate labels.

To make a bar diagram with matplotlib, use the matplotlib.pyplot.bar() method. Have a look at this page of the matplotlib documentation that explains very well with examples and source code how to do it.

If it is possible though, I would just suggest that for a simple task like this if you could avoid writing code that would be better. If you have any spreadsheet program this should be a piece of cake because that's exactly what they are for, and you won't have to 'reinvent the wheel'. The following is the plot of your data in Excel:

Bar diagram plot in Excel

I just copied your data from the question, used the text import wizard to put it in two columns, then I inserted a column diagram.

Abhranil Das
  • 5,702
  • 6
  • 35
  • 42
  • 2
    Thanks for your answer but I have to do it in Python. – mazix Jul 23 '12 at 21:22
  • 7
    This is not reinventing the wheel, it is using a different tool. Using your argument there would be no point in learning how to draw line graphs in matplotlib because you could just do it in Excel – Anake Jul 22 '14 at 12:49
  • 2
    "if you could avoid writing code that would be better." why? i can't imagine many people on SO will be sympathetic to that statement. – abcd Apr 02 '15 at 21:06
  • I don't know why this answer has so many downvotes. Well seems answer was edited much later. – Aditya Jun 29 '15 at 03:03