3

I'm working with a dictionary of values which have a string (date) and float for time in milliseconds. I want to present the data in a bar graph and also with a table below. I have the bar graph working but the table gets messed up. I want the dates as columns and time as a single row.

The dictionary is something like:

time_and_dates_for_plot = {'04-26': 488.1063166666667, '04-27': 289.7289333333333, '04-28': 597.2343999999999, '04-29': 0, '04-30': 0, '05-01': 1061.958075}

plot.bar(range(len(time_and_dates_for_plot)), time_and_dates_for_plot.values(), align='center')
plot.xticks(range(len(time_and_dates_for_plot)), list(time_and_dates_for_plot.keys()))
plot.xlabel('Date (s)')
plot.ylabel('milliseconds')
plot.grid(True)
plot.gca().set_position((.1, .3, .8, .6))
col_labels = list(time_and_dates_for_plot.keys())
print(col_labels)
row_labels = ['ms']
cell_text = []
val = []

for key in time_and_dates_for_plot.keys():
    val.append((time_and_dates_for_plot.get(key)))
    cell_text.append(val)
    val = []
print(cell_text)
plot.table(cellText=cell_text, colLabels=col_labels)
plot.show()

Plot and table

As you can see from the picture, I get all entries under one column where as I want something like one cell data under one coloumn (just tabulate plot data).

Also, how do I add some padding between the table and graph?

First time I'm using matplotlib and pretty sure I'm missing something. Any help is really appreciated.

1 Answers1

6

In the table function you need an extra pair of brackets []. ...cellText=[cell_text]... Also, you can use subplots to have a better arrangement of the plots. Here, my solution uses subplots of 2 rows withheight_ratiosof 8 to 1, and ahspace` pf 0.3

import matplotlib as mpl
import matplotlib.pyplot as plt

time_and_dates_for_plot = {'04-26': 488.1063166666667,
                           '04-27': 289.7289333333333,
                           '04-28': 597.2343999999999,
                           '04-29': 0,
                           '04-30': 0,
                           '05-01': 1061.958075}

fig,axs = plt.subplots(figsize=(8,5),ncols=1,nrows=2,
                           gridspec_kw={'height_ratios':[8,1],'hspace':0.3})
ax = axs[0]
ax.bar(range(len(time_and_dates_for_plot)),
            time_and_dates_for_plot.values(), align='center')
ax.set_xticks(range(len(time_and_dates_for_plot)),
                list(time_and_dates_for_plot.keys()))
ax.set_xlabel('Date (s)')
ax.set_ylabel('milliseconds')
ax.grid(True)

col_labels = list(time_and_dates_for_plot.keys())
row_labels = ['ms']
cell_text = []

for key in time_and_dates_for_plot.keys():
    cell_text += [time_and_dates_for_plot[key]]

ax = axs[1]
ax.set_frame_on(False) # turn off frame for the table subplot
ax.set_xticks([]) # turn off x ticks for the table subplot
ax.set_yticks([]) # turn off y ticks for the table subplot
ax.table(cellText=[cell_text], colLabels=col_labels, loc='upper center')
plt.show()

The output looks like:

enter image description here

** UPDATE **

Using only one subplot, no xticklabels, sorted dates, nicer numbers with %g, and larger table cells using bbox :

import matplotlib as mpl
import matplotlib.pyplot as plt

time_and_dates_for_plot = {'04-26': 488.1063166666667,
                           '04-27': 289.7289333333333,
                           '04-28': 597.2343999999999,
                           '04-29': 0,
                           '04-30': 0,
                           '05-01': 1061.958075}
N = len(time_and_dates_for_plot)
colLabels = sorted(time_and_dates_for_plot.keys())
fig,ax = plt.subplots()
aa = ax.bar(range(N),[time_and_dates_for_plot[x] for x in colLabels],
                    align='center')
ax.set_xlabel('Date')
ax.set_ylabel('milliseconds')
ax.set_xticklabels([]) # turn off x ticks
ax.grid(True)

fig.subplots_adjust(bottom=0.25) # making some room for the table

cell_text = []
for key in colLabels:
    cell_text += ["%g"%time_and_dates_for_plot[key]]

ax.table(cellText=[cell_text], colLabels=colLabels,
                    rowLabels=['ms'],cellLoc='center',
                    bbox=[0, -0.27, 1, 0.15])
ax.set_xlim(-0.5,N-0.5) # Helps having bars aligned with table columns
ax.set_title("milliseconds vs Date")
fig.savefig("Bar_graph.png")
plt.show()

Output:

enter image description here

** Update: Making room for the table using subplots_adjust **

Pablo Reyes
  • 3,073
  • 1
  • 20
  • 30
  • Thanks a lot for the answer. I have couple of questions. How do I use title and savefig methods from the plot class. When I try accessing plot.title or plot.savefig they don't work. Also, the same result when I use ax or fig. I couldn't find documentation for these options of formatting. Could you point me to those please? Thanks in advance. – Srikkanth Govindaraajan May 02 '17 at 20:12
  • You should use the convention `plt` instead of `plot` with the usual `import matplotlib.pyplot as plt`. Also, the variable `fig` which is of type `matplotlib.figure.Figure` has `savefig` method. For title and axis labels use `ax`. e.g. ax.set_title() – Pablo Reyes May 02 '17 at 20:20
  • @srikbaba If this answer or another that might come later solved your issue, please mark it as accepted. – Pablo Reyes May 02 '17 at 22:10
  • 1
    @srikbaba I have updated my answer doing several changes, simplifying it and making it nicer. The dates are also sorted using `sorted()` and only one subplot has been used. `bbox` has been used inside `table` in order to increase the size of the table/cells. I have also included a title using `ax.set_title()` and saved the figure using `fig.savefig()` – Pablo Reyes May 03 '17 at 04:42
  • I ran the provided code, I don't see the table completely. http://imgur.com/a/1cyha why is this happening? – Srikkanth Govindaraajan May 03 '17 at 15:03
  • 1
    @srikbaba When I first started I visited a lot the gallery of graphs that can be done with `matplotlib`, i.e. http://matplotlib.org/gallery.html All the `pyplot` (that by convention is imported as plt as shown in my code) methods are listed and explained here http://matplotlib.org/api/pyplot_summary.html And if you are using `IPython` of `jupyter` and you have loaded `plt` or `fig` or `ax` you just put a dot and hit the `tab` key and you will see suggestions of what methods are available. you can also execute `ax.set_title?` with one or two question marks and you will have some quick info. – Pablo Reyes May 03 '17 at 15:07
  • @srikbaba What is happening is that `bbox` with -0.25 is pushing things out of the plotting box. We can use the first method, or make some room. I have updated my answer with a line that makes some room for the table: `fig.subplots_adjust(bottom=0.25)` That pushes the bottom upwards. It should work now. – Pablo Reyes May 03 '17 at 15:16
  • Yes works very well. Thank you for the quick response. – Srikkanth Govindaraajan May 03 '17 at 15:49