在matplotlib条形图上绘制3个类别,其中一个类别的x轴部分没有值

dzhpxtsq  于 2022-10-22  发布在  Python
关注(0)|答案(1)|浏览(200)

我一直在使用自己的IMDB数据来练习Pandas和绘图,并创建了一个条形图,用来显示电视剧、电影和电视剧三种收视率之间的收视率分布。
问题是,我的数据集中没有任何电视剧的评分为1或2。我想在电视系列的x轴上显示1和2的0%。
这是我迄今为止想出的代码:

  1. fig, ax = plt.subplots(figsize=(10,4))
  2. x_axis = np.arange(1,11)
  3. movies_x = movies['your rating'].value_counts(normalize=True).sort_index()*100
  4. tvseries_x = tvseries['your rating'].value_counts(normalize=True).sort_index()*100
  5. tveps_x = tveps['your rating'].value_counts(normalize=True).sort_index()*100
  6. width = 0.3
  7. ax.bar(x_axis-width, movies_x, width, label = 'Movies')
  8. ax.bar(x_axis, tveps_x, width, label = 'Episodes')
  9. ax.bar(x_axis[2:]+width, tvseries_x, width, label = 'Series')
  10. ax.bar_label(ax.containers[0], color='blue', fmt='%.f%%', fontsize=8)
  11. ax.bar_label(ax.containers[1], color='red', fmt='%.f%%', fontsize=8)
  12. ax.bar_label(ax.containers[2], color='green', fmt='%.f%%', fontsize=8)
  13. ax.set_xticks(x_axis)
  14. ax.set_xlabel('Rating')
  15. ax.set_ylabel('Percent')
  16. ax.set_title('Rating Distribution per rating type')
  17. ax.legend(loc=6)
  18. plt.tight_layout()
  19. plt.show()


小时
我的解决方法是从3-10(x_axis[2:])开始绘制电视剧,否则我会得到“ValueError:形状不匹配:对象无法广播到单个形状。不匹配是形状为(10,)的arg 0和形状为(8,)的参数1之间。”
我在这里搜索了很多,我所能找到的只是分布基于X轴的问题(例如每个评级组的百分比)。手动编辑系列以添加1、2似乎不是一个理想的解决方案。
请提供任何意见/建议。
谢谢

cygmwpex

cygmwpex1#

由于没有提供数据,我将通过生成电影评级的(假)数据集来回答这个问题。

再现错误:

  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. import random
  4. import numpy as np
  5. # The dataframe will have one column with movie ratings from 3 to 10.
  6. movies = pd.DataFrame({"your rating" : random.choices(range(3, 11), k = 100)})
  7. fig, ax = plt.subplots(figsize=(10,4))
  8. x_axis = np.arange(1, 11)
  9. # Get percentage of ratings
  10. movies_x = movies['your rating'].value_counts(normalize=True).sort_index()*100
  11. ax.bar(x_axis, movies_x, label = 'Movies')
  12. ax.bar_label(ax.containers[0], color='blue', fmt='%.f%%', fontsize=8)
  13. ax.set_xticks(x_axis)
  14. ax.set_xlabel('Rating')
  15. ax.set_ylabel('Percent')
  16. ax.set_title('Rating Distribution per rating type')
  17. ax.legend(loc=6)
  18. plt.tight_layout()
  19. plt.show()

这给出了错误:
ValueError: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (10,) and arg 1 with shape (8,).

解决错误:

您必须确保以_x结尾的系列(存储不同评级的百分比)具有从1到10的索引。要做到这一点,不必担心哪些评级不会出现在数据集中,我们可以尝试:

  1. random.seed(100)
  2. movies = pd.DataFrame({"your rating" : random.choices(range(3, 11), k = 100)})
  3. fig, ax = plt.subplots(figsize=(10,4))
  4. x_axis = np.arange(1, 11)
  5. # Get percentage of ratings
  6. movies_x = movies['your rating'].value_counts(normalize=True).sort_index()*100
  7. # Code of interest
  8. ratings = dict.fromkeys(set(range(1, 10)).difference(movies_x.index), 0)
  9. movies_x = movies_x.combine(pd.Series(ratings), max, 0)
  10. print(movies_x)
  11. ax.bar(x_axis, movies_x, label = 'Movies')
  12. ax.bar_label(ax.containers[0], color='blue', fmt='%.f%%', fontsize=8)
  13. ax.set_xticks(x_axis)
  14. ax.set_xlabel('Rating')
  15. ax.set_ylabel('Percent')
  16. ax.set_title('Rating Distribution per rating type')
  17. ax.legend(loc=6)
  18. plt.tight_layout()
  19. plt.show()

这使得movies_x为:
并且该图形输出为:


小时

展开查看全部

相关问题