【问题标题】:Plotting by ignoring missing data in matplotlib通过忽略 matplotlib 中的缺失数据进行绘图
【发布时间】:2020-12-25 01:10:46
【问题描述】:

我一直在尝试制作一个程序,该程序可以在 2 人之间的 Whatsapp 聊天期间绘制一个单词的使用频率。例如,night 这个词在几天内被使用了几次,而在大部分时间里被使用了 0 次。我的图如下

这里是代码

word_occurances = [0 for i in range(len(just_dates))]

for i in range(len(just_dates)):
    for j in range(len(df_word)):
        if just_dates[i].date() == word_date[j].date():
            word_occurances[i] += 1

title = person2.rstrip(':') + ' with ' + person1.rstrip(':') + ' usage of the word - ' + word

plt.plot(just_dates, word_occurances, color = 'purple')
plt.gcf().autofmt_xdate()
plt.xlabel('Time')
plt.ylabel('number of times used')
plt.title(title)
plt.savefig('Graphs/Words/' + title + '.jpg', dpi = 200)
plt.show()

word_occurrances 是一个列表

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

我想要的是图表仅连接使用它的点,同时在 x 轴上显示整个时间线。我不希望图表触及 0。我该怎么做?我搜索并找到了类似的答案,但没有一个能像我一样工作。

【问题讨论】:

    标签: python python-3.x pandas numpy matplotlib


    【解决方案1】:

    您只需找到对应值大于零的word_occurances 的索引。有了这个你可以索引just_dates来获取相应的日期。

    word_counts = []    # Only word counts > 0
    dates = []          # Date of > 0 word count
    for i, val in enumerate(word_occurances):
        if val > 0:
            word_counts.append(val)
            dates.append(just_dates[i])
    

    您可能希望使用底层条形图进行绘图以保持原始比例。

    plt.bar(just_dates, word_occurances)
    plt.plot(dates, word_counts, 'r--')
    

    【讨论】:

      【解决方案2】:

      解决此问题的一种方法是仅绘制包含条目的数据,但标记对话发生的所有日期以指示图表中的零值:

      from matplotlib import pyplot as plt
      import matplotlib.dates as mdates
      from matplotlib.ticker import FixedLocator
      
      #fake data generation, this block just imitates your unknown data and can be deleted
      import numpy as np
      import pandas as pd
      np.random.seed(12345)
      n = 30
      just_dates = pd.to_datetime(np.random.randint(1, 100, n)+18500, unit="D").sort_values().to_list()
      word_occurances = [0]*n
      for i in range(10): 
          word_occurances[np.random.randint(n)] = np.random.randint(1, 10)
      
      
      fig, ax = plt.subplots(figsize=(15,5))
      
      #generate data to plot by filtering out zero values
      plot_data = [(just_dates[i], word_occurances[i]) for i, num in enumerate(word_occurances) if num > 0]
      
      #plot these data with marker to indicate each point 
      #think 1-1-1-1-1 would only be visible as two points with lines only
      ax.plot(*zip(*plot_data), color = 'purple', marker="o")
      #label all dates where conversations took place
      ax.xaxis.set_major_locator(FixedLocator(mdates.date2num(just_dates)))
      #prevent that matplotlib autoscales the y-axis
      ax.set_ylim(0, )
      ax.tick_params(axis="x", labelrotation= 90)
      
      plt.xlabel('Time')
      plt.ylabel('number of times used')
      plt.title("Conversations at night")
      plt.tight_layout()
      plt.show()
      

      示例输出:

      所有这些日期标签很快就会变得很忙(并且可能会或可能不会与 just_dates 中的日期时间对象一起使用,这些对象的结构可能与我的示例日期不同)。另一种方法是用vlines 表示每个对话:

      ...
      fig, ax = plt.subplots(figsize=(15,5))
      
      plot_data = [(just_dates[i], word_occurances[i]) for i, num in enumerate(word_occurances) if num > 0]
      
      ax.plot(*zip(*plot_data), color = 'purple', marker="o")
      ax.vlines((just_dates), 0, max(word_occurances), color="red", ls="--")
      ax.set_ylim(0, )
      
      plt.gcf().autofmt_xdate()
      plt.xlabel('Time')
      plt.ylabel('number of times used')
      plt.title("Conversations at night")
      plt.tight_layout()
      plt.show()
      

      示例输出:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 2021-03-21
        • 2020-11-07
        • 2012-08-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多