【问题标题】:How to properly plot a bar chart in a Pandas dataframe? The x-values keep showing up as the index如何在 Pandas 数据框中正确绘制条形图? x 值继续显示为索引
【发布时间】:2020-11-21 21:53:33
【问题描述】:

我有一个小数据框,其中包含 student_id、exam_1、exam_2、exam_3、exam_4 和exam_5 作为列。行也有 5 名学生。我想做的是绘制一个条形图,显示一个学生的考试成绩,也就是一个特定的行,并最终根据用户输入为每个或一个特定的学生做这件事。

不过,目前,我还停留在如何为一个特定的学生绘制条形图。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'student_id': [83838, 16373, 93538, 29383, 58585],
                   'exam_1': [80, 95, 90, 75, 50],
                   'exam_2': [60, 92, 88, 85, 40],
                   'exam_3': [70, 55, 75, 45, 60],
                   'exam_4': [55, 95, 45, 80, 55],
                   'exam_5': [91, 35, 92, 90, 75]})

print(df)

产生这个作为输出:

  student_id  exam_1  exam_2  exam_3  exam_4  exam_5
0       83838      80      60      70      55      91
1       16373      95      92      55      95      35
2       93538      90      88      75      45      92
3       29383      75      85      45      80      90
4       58585      50      40      60      55      75

在下面添加此代码将允许我只选择一个特定的学生 ID 即行:

df = df.loc[df['student_id'] == 29383]
print(df)
   student_id  exam_1  exam_2  exam_3  exam_4  exam_5
3       29383      75      85      45      80      90

从这里我想在条形图中绘制这个特定学生的考试。

我尝试了下面的代码,但它没有显示我想要的样子。如果您能看到图像,似乎这个特定学生的索引被用于 x 轴上的刻度。它将显示“3”,周围有一些条形图。

exam_plots_for_29383 = df.plot.bar()
plt.show()

这将输出此条形图: Dataframe with bar plot. Looks weird.

我尝试转置数据框,这让我得到了我想要的。我在下面使用了这段代码:

df = df.T
exam_plots_for_29383_T = df.plot.bar()
plt.show()

但我最终得到了这个图表: Transpose of dataframe with bar plot. Looks weird still.

我有点卡住了。我知道有一种从数据框中正确绘制条形图的合乎逻辑的方法,但我一生都无法弄清楚。

我想要条形图:

  • 考试 1 到 5 显示在 x 轴上。
  • 它们在 y 轴上的值。
  • 每个考试栏都有不同的颜色。
  • 显示颜色的图例。

我认为最后两个选项是自动完成的。只是前两个让我心碎。感谢您提供任何帮助或提示。

这是完整的代码,以防有人希望看到它而不像上面那样拆分它。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'student_id': [83838, 16373, 93538, 29383, 58585],
                   'exam_1': [80, 95, 90, 75, 50],
                   'exam_2': [60, 92, 88, 85, 40],
                   'exam_3': [70, 55, 75, 45, 60],
                   'exam_4': [55, 95, 45, 80, 55],
                   'exam_5': [91, 35, 92, 90, 75]})

print(df)

df = df.loc[df['student_id'] == 29383]
print(df)

exam_plots_for_29383 = df.plot.bar()
plt.show()

df = df.T
exam_plots_for_29383_T = df.plot.bar()
plt.show()  

【问题讨论】:

  • @anky 这与我正在寻找的非常接近!我真的很喜欢这个,因为它很有用!但是,我不想让每个刻度都是一个学生 ID,并将他们的所有考试(1、2、3、4、5)作为条形图,我希望整个图表成为一个特定学生考试的条形图。因此,在底部的刻度将是“考试 1、考试 2、考试 3、考试 4、考试 5”,它们各自的每门考试分数将是 y 值。我觉得我每次都很接近,但我缺少一些东西。

标签: python pandas


【解决方案1】:

你很亲密。问题是您的类似数字的学生 ID 弄乱了所有图表(这就是为什么 ID 29383 在您的所有图表中为您提供了一个接近 30,000 的条形图)。

将“student_id”设置为索引,这样它就不会被绘制出来,现在您可以使用.loc[student_id] 分别绘制每个学生对索引进行切片,或者如果您绘制整个DataFrame,它将为每个不同的学生着色。

df = df.set_index('student_id')
df.loc[29383].plot(kind='bar', figsize=(4,3), rot=30)

知道有 5 种考试,如果你真的想要,你可以给每一种考试自己的颜色。使用分类调色板 (tab10)。 (这也适用于 Series.plot)

from matplotlib import cm
df.loc[29383].plot(kind='bar', figsize=(4,3), rot=30, color=cm.tab10.colors[0:5])

【讨论】:

  • 做到了!太感谢了。出于某种原因,起初它似乎并不那么直观。更好地结构化数据会更容易吗?例如,我对数据框所做的第一次打印一开始似乎是合乎逻辑的,以 student_id 和考试 1-5 作为列,直到我决定绘制它。我的想法是每个新学生,他们的考试成绩可以添加为行。我想让我遇到麻烦的是把它想象成一个 Excel 表格并以这种方式制作数据框。
  • @GregGoodbread 组织很好。我稍微更改了解决方案以使其保持原样,它只需要您设置索引,然后使用 .loc 选择一行,而不是转置
猜你喜欢
  • 2016-03-18
  • 2021-09-27
  • 1970-01-01
  • 2021-09-17
  • 2018-09-28
  • 2016-12-31
  • 2020-12-13
  • 1970-01-01
相关资源
最近更新 更多