【问题标题】:Plotting two lists of different length matplotlib against same x value根据相同的 x 值绘制两个不同长度的 matplotlib 列表
【发布时间】:2019-06-30 15:50:56
【问题描述】:

我有两个numpy.ndarraysbcmonthlydailyavg

bcmonthly has a length of 12 and shape of (12,)

dailyavg has a length of 364 and shape of (364,)

bcmonthy 是月平均值,dailyavg 是日平均值。我想根据 12 个月的 x 轴绘制这两个变量。

绘制 bcmonthly 没有问题,因为它的形状是 12。但是,当我同时绘制 dailyavg 时,我得到了这个错误:

ValueError: x and y must have same first dimension, but have shapes (12,) and (364,)

下面是我的代码:

fig = plt.figure()  
ax1=fig.add_subplot(111)
ax1.plot(months,bcmonthly,'r') #months is a list months=['jan','feb',..etc]
ax2 = ax1.twinx()
ax2.plot(months, dailyavg)   
plt.show()

【问题讨论】:

标签: python matplotlib time-series


【解决方案1】:

如果您想将日平均值与月平均值绘制在同一个图上,则可能更容易构建两个数组并将它们都绘制在一组天数上,然后自己处理标签。像这样的

import matplotlib.pyplot as plt
import numpy as np

bcmonthly = np.random.rand(12)    # Creates some random example data,
dailyavg = np.random.rand(365)    # use your own data in place of this
days = np.linspace(0, 364, 365)
months = ['January', 'February', 'March', 'April', 'May',
          'June', 'July', 'August', 'September',
          'October', 'November', 'December']

lmonths = [0, 2, 4, 6, 7, 9, 11]
smonths = [3, 5, 8, 10]
month_idx = list()
idx = -15      # Puts the month avg and label in the center of the month
for jj in range(len(months)):
    if jj in lmonths:
        idx += 31
        month_idx.append(idx)
    elif jj in smonths:
        idx += 30
        month_idx.append(idx)
    elif jj == 1:
        idx += 28
        month_idx.append(idx)

fig = plt.figure(figsize=(10,4), dpi=300)  
plt.plot(month_idx,bcmonthly,'r')
plt.plot(days, dailyavg, ':', linewidth=1)
plt.xlim([-1,366])
plt.title("Monthly and Daily Averages")
plt.xticks(month_idx, months, rotation=45)
plt.show()

这给了你

或者,您可以使用ax.plot() 的面向对象方法,但这需要您分别指定刻度标签和位置,

import matplotlib.pyplot as plt
import numpy as np

bcmonthly = np.random.rand(12)
dailyavg = np.random.rand(365)
days = np.linspace(0, 364, 365)
months = ['January', 'February', 'March', 'April', 'May',
          'June', 'July', 'August', 'September',
          'October', 'November', 'December']

lmonths = [0, 2, 4, 6, 7, 9, 11]
smonths = [3, 5, 8, 10]
month_idx = list()
idx = -15      # Puts the month avg and label in the center of the month
for jj in range(len(months)):
    if jj in lmonths:
        idx += 31
        month_idx.append(idx)
    elif jj in smonths:
        idx += 30
        month_idx.append(idx)
    elif jj == 1:
        idx += 28
        month_idx.append(idx)

fig = plt.figure(figsize=(10,4), dpi=300)  
ax1 = fig.add_subplot(111)
ax1.plot(month_idx,bcmonthly,'r')
ax2 = ax1.twinx()
ax2.plot(days, dailyavg, ':', linewidth=1)
plt.xlim([-1,366])
plt.title("Monthly and Daily Averages")
ax1.set_xticklabels(months, rotation=45)
ax1.set_xticks(month_idx)
plt.show()

【讨论】:

  • 感谢您的详细回复。我通过实施解决了它: x1=np.linspace(0,12,364) x2=np.linspace(0,12,12) plt.plot(x1,dailyavg,'r') plt.plot(x2,bcmonthly) plt.显示()。这似乎已经解决了这个问题。
  • 嗨@Ghost。有没有办法用面向对象的技术来解决这个问题。我需要更多的控制。使用 ax.plot?
【解决方案2】:

在绘制 monthsdailyavg 时,您需要将 months 扩展为长度为 364——Matplotlib 无法为您决定 months 中的 12 个 x 值中的哪一个来分配 364 个每日平均值到,但您可以通过制作适当长度的 x 值列表自己提供该信息。

因此,在这种情况下,这似乎意味着制作一个包含 "January" 31 次的列表,然后是 "February" 28 次,依此类推...直到您达到长度 364(取决于缺少哪一天?)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2015-09-09
    • 2014-02-08
    • 2012-07-29
    • 1970-01-01
    相关资源
    最近更新 更多