1

I'm trying to create a chart similar to the image attached. enter image description here

I plan to use matplotlib but I'm not sure which type of chart to use.

The chart at the bottom shows people going In and Out from a bus. The chart at the top shows door opening and closing at a specific time.

The chart is build from a csv file with timestamps for door events and timestamps for counting events.

For now, I was thinking to use the plot() function for the bottom chart and the bar() function for the top chart.

Do you think this would work ? Should I use something else ?

Also, do you think I should use plt.subplot() to plot the 2 charts or should I plot both on the same chart ?

Any example would be great.

Thanks for your time, ssinfod

1
  • I know this is a while ago, but did you ever get something working the way you want? Commented Jul 17, 2015 at 3:45

2 Answers 2

1

I like @jcoppens idea with axhspan. Here is an example using bar on top and step for the main plot. The top bar chart corresponds to the orange step plot on the bottom, and similarly for the green bar chart.

The orange or green color map in the bar charts corresponds to the number of people coming in (determined by a positive value in the associated step plot - by associated I mean green with green, orange with orange). The grayscale corresponds to people going out (determined by negative values in the associated step plot).

enter image description here

Code to generate the plot:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
import matplotlib.colors as col

hr = ['{num:02d}'.format(num=i) for i in range(24)]
times = ['{0}:00'.format(h) for h in hr ]
tick_location = [t*4 for t in range(24)]

x1 = np.random.randint(-10, 20, 4*24)
x1[0:5] = 0
x1[20:30] = 0
x1[42:57] = 0
x1[69:74] = 0
x2 = np.random.randint(-3, 5, 4*24)
x2[0:25] = 0
x2[48:57] = 0
x2[89:] = 0

What you actually care about:

cmap_in_x1 = cm.ScalarMappable(col.Normalize(min(x1), max(x1)), 'Greens')
cmap_in_x2 = cm.ScalarMappable(col.Normalize(min(x2), max(x2)), 'Oranges')
cmap_out = cm.ScalarMappable(col.Normalize(min(x1), max(x1)), 'bone')

fig = plt.figure(figsize=(12,8))

big_ax = fig.add_axes([0.1, 0.1, 0.8, 0.6])
plt.grid()

small_ax_1 = fig.add_axes([0.1, 0.7, 0.8, 0.05], sharex=big_ax)
small_ax_2 = fig.add_axes([0.1, 0.75, 0.8, 0.05], sharex=big_ax)

big_ax.step(np.arange(len(x1)), x1, color='lightgreen', alpha=0.8, linewidth=2)
big_ax.step(np.arange(len(x2)), x2, color='orange', alpha=0.5, linewidth=2)

small_ax_1.bar(np.arange(len(x1>0)), x1>0, align='center', alpha=0.8, color=cmap_in_x1.to_rgba(x1))
small_ax_1.bar(np.arange(len(x1<0)), x1<0, align='center', alpha=1.0, color=cmap_out.to_rgba(x1))
small_ax_2.bar(np.arange(len(x2>0)), x2>0, align='center', alpha=0.8, color=cmap_in_x2.to_rgba(x2))
small_ax_2.bar(np.arange(len(x2<0)), x2<0, align='center', alpha=1.0, color=cmap_out.to_rgba(x2))

big_ax.set_xticks(tick_location)
big_ax.set_xticklabels(times, rotation=90)

big_ax.plot(np.zeros(len(x1)), color='black', linewidth=2)

plt.setp(small_ax_1.get_yticklabels(), visible=False)
plt.setp(small_ax_1.get_xticklabels(), visible=False)
plt.setp(small_ax_2.get_yticklabels(), visible=False)
plt.setp(small_ax_2.get_xticklabels(), visible=False)

plt.title('Bus Traffic', fontsize=24)
plt.show()
Sign up to request clarification or add additional context in comments.

Comments

0

The subplot idea seems very good.

For the top graphs you might like to consider axhspan instead of bars. Bars tend to have the same width which might complicate your work. with axhspan you just define from where to where you want a bar to be drawn.

A simple example are the middle bars in this image, which indicate the daylight zones at the observer and the transmitter sites:

enter image description here

The code is something like this:

s.axhspan(y1, y2, xmin = 0., xmax = set, ec = 'black', fc = 'white', lw = 1)
s.axhspan(y1, y2, xmin = set, xmax = rise, linewidth=4, color='black', lw = 1)
s.axhspan(y1, y2, xmin = rise, xmax = 1., ec = 'black', fc = 'white', lw = 1)

where the xmin/xmax are the changes in day/night (in my case), but would be the opening/closing of the doors.

The plot preparation (in my plot) is like this:

s = plt.subplot(where, ylabel='Sun', xlim = (0., 24.), ylim = (0., 1.), \
                xticks = xticks, \
                yticks = [0.25, 0.75], yticklabels = [id, 'Obs'], \
                axisbg = '#00c000')

And, in the same plot, draws both bars, just specifying their heights (ymin and ymax)

1 Comment

Thanks I will have a look at axhspan and subplot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.