python - matplotlib:创建两个(堆叠的)具有共享 X 轴但独立 Y 轴值的子图

标签 python matplotlib

我在 Ubuntu 10.0.4 上使用 matplotlib 1.2.x 和 Python 2.6.5。我正在尝试创建一个由顶部图和底部图组成的 SINGLE 图。

X 轴是时间序列的日期。顶部图包含数据的烛台图,底部图应包含条形图 - 具有自己的 Y 轴(也在左侧 - 与顶部图相同)。这两个图不应重叠。

这是我到目前为止所做的一个片段。

datafile = r'/var/tmp/trz12.csv'
r = mlab.csv2rec(datafile, delimiter=',', names=('dt', 'op', 'hi', 'lo', 'cl', 'vol', 'oi'))

mask = (r["dt"] >= datetime.date(startdate)) & (r["dt"] <= datetime.date(enddate))
selected = r[mask]
plotdata = zip(date2num(selected['dt']), selected['op'], selected['cl'], selected['hi'], selected['lo'], selected['vol'], selected['oi'])

# Setup charting 
mondays = WeekdayLocator(MONDAY)        # major ticks on the mondays
alldays    = DayLocator()               # minor ticks on the days
weekFormatter = DateFormatter('%b %d')  # Eg, Jan 12
dayFormatter = DateFormatter('%d')      # Eg, 12
monthFormatter = DateFormatter('%b %y')

# every Nth month
months = MonthLocator(range(1,13), bymonthday=1, interval=1)

fig = pylab.figure()
fig.subplots_adjust(bottom=0.1)
ax = fig.add_subplot(111)
ax.xaxis.set_major_locator(months)#mondays
ax.xaxis.set_major_formatter(monthFormatter) #weekFormatter
ax.format_xdata = mdates.DateFormatter('%Y-%m-%d')
ax.format_ydata = price
ax.grid(True)

candlestick(ax, plotdata, width=0.5, colorup='g', colordown='r', alpha=0.85)

ax.xaxis_date()
ax.autoscale_view()
pylab.setp( pylab.gca().get_xticklabels(), rotation=45, horizontalalignment='right')

# Add volume data 
# Note: the code below OVERWRITES the bottom part of the first plot
# it should be plotted UNDERNEATH the first plot - but somehow, that's not happening
fig.subplots_adjust(hspace=0.15)
ay = fig.add_subplot(212)
volumes = [ x[-2] for x in plotdata]
ay.bar(range(len(plotdata)), volumes, 0.05)

pylab.show()

我已经设法使用上面的代码显示了两个图,但是,底部图有两个问题:

  1. 它完全覆盖了第一个(顶部)图的底部 - 几乎就像第二个图绘制在与第一个图相同的“ Canvas ”上一样 - 我看不出发生的位置/原因.

  2. 它用自己的索引覆盖现有的 X 轴,X 轴值(日期)应在两个图之间共享。

我的代码哪里做错了?有人可以找出导致第二个(底部)图覆盖第一个(顶部)图的原因 - 我该如何解决这个问题?

这是上面代码创建的图的屏幕截图:

faulty plot

[[编辑]]

根据 hwlau 的建议修改代码后,这是新的情节。它比第一个更好,因为两个图是分开的,但是仍然存在以下问题:

  1. X 轴应该由两个图共享(即 X 轴应该只显示第二个[底部]图)

  2. 第二个图的 Y 值格式似乎不正确

partly correct plot

我认为这些问题应该很容易解决,但是,我的 matplotlib fu 目前不是很好,因为我最近才开始使用 matplotlib 编程。任何帮助将不胜感激。

最佳答案

您的代码似乎有几个问题:

  1. 如果您使用的是完整的 figure.add_subplots subplot(nrows, ncols, plotNum) 的签名可能有 更明显的是你的第一个情节要求一行 和 1 列,第二个图要求 2 行和 1 列。因此,您的第一个情节正在填满整个数字。 而不是 fig.add_subplot(111) 后跟 fig.add_subplot(212) 使用 fig.add_subplot(211),然后使用 fig.add_subplot(212)

  2. 共享轴应该在 add_subplot 命令中使用 sharex=first_axis_instance

我整理了一个您应该能够运行的示例:

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import matplotlib.dates as mdates


import datetime as dt


n_pts = 10
dates = [dt.datetime.now() + dt.timedelta(days=i) for i in range(n_pts)]

ax1 = plt.subplot(2, 1, 1)
ax1.plot(dates, range(10))

ax2 = plt.subplot(2, 1, 2, sharex=ax1)
ax2.bar(dates, range(10, 20))

# Now format the x axis. This *MUST* be done after all sharex commands are run.

# put no more than 10 ticks on the date axis.  
ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
# format the date in our own way.
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

# rotate the labels on both date axes
for label in ax1.xaxis.get_ticklabels():
    label.set_rotation(30)
for label in ax2.xaxis.get_ticklabels():
    label.set_rotation(30)

# tweak the subplot spacing to fit the rotated labels correctly
plt.subplots_adjust(hspace=0.35, bottom=0.125)

plt.show()

希望对您有所帮助。

关于python - matplotlib:创建两个(堆叠的)具有共享 X 轴但独立 Y 轴值的子图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10007016/

相关文章:

python - 在 Python Pandas 中格式化字符串数字

python - 如何为所有子图设置一个颜色条

python - matplotlib 堆叠条形图 AssertionError : incompatible sizes: argument 'bottom' must be length 3 or scalar

python - 如何创建分离器网格

python - 将图像从 C++ 传递到 Python 3.4

python - numpy.isfinite() 中的意外异常

python - 如何制作按轴 1 分组的箱线图

python - 如何在Win11下显示WSL2中的matplotlib窗口?

python - 在 matplotlib 中扩展线段

python - 如何在非常大的 torch 张量上执行操作而不拆分它们