2
votes

I want to display bars on a time series chart with proper bar widths.

fig,ax1=plt.subplots()

x_nums = list(range(50))
x_dates = pd.date_range(date_from,periods=50,freq='h')
y1 = list(range(50))
y2=y1.copy()
y2.reverse()

ax1.plot(x_nums, y1, color='r',zorder=10,linewidth=5)
# ax1.plot(x_dates, y1, color='r',zorder=10,linewidth=5)

ax2=ax1.twinx()    
ax2.bar(x_nums, y2, color='b',zorder=1,alpha=0.3)
# ax2.bar(x_dates, y2, color='b',zorder=1,alpha=0.3)

when I plot this with x_nums, left image will be shown, if with x_dates, right will be shown.

bar plot


  1. How can I make bars of proper width, ie the same as on image 1? I know I can set ax2.bar(width=.1) or something but I want to generate many charts with different number of ticks and sizes and I just want matplotlib to maintain proper widths as it does if x_nums is the X axis.
    I tried setting witdth = 1/len(x_dates) but that did not work for charts with lots of ticks as it makes the bars too thin.
    [EDIT] answer: upgrade matplotlib to version where width accepts np.timedelta, then
    ax2.bar(x_dates, y2, width=(x_dates[1]-x_dates[0])*0.8)
  1. How can I send ax1 to front? zorder is not working in this case. I still want y1 to be on left side and y2 to be on right side.
    [EDIT] answer: PyPlot move alternative y axis to background

Thank you!

1
And for the second question: stackoverflow.com/questions/46645280/… - TheIdealis
@rafaelgonzalez seen that one, does not help. The width is fixed in that answer, but I want the width to change based on how any rows of data I am plotting. (narrow for a lot of data, wide for few data) - storm_88
Newer versions of matplotlib allow the width to be specified as a timedelta. - Jody Klymak
@JodyKlymak could you please post some link? Can't find it - storm_88

1 Answers

1
votes

You can specify widths as np.timedelta64 objects. Or note that a width of 1.0 is 1 day, so to get 40-minute wide bars, you'd specify width=40/24/60

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

fig,ax1=plt.subplots()
date_from = '2019-01-01'

x_nums = list(range(50))
x_dates = pd.date_range(date_from,periods=50,freq='h')
y1 = np.arange(50)
y2=y1[::-1]

ax1.plot(x_dates, y1, color='r',zorder=10,linewidth=5)
ax2=ax1.twinx()
ax2.bar(x_dates, y2, color='b',zorder=1,alpha=0.3, width=np.timedelta64(40, 'm'))
plt.show()

enter image description here