首页 > 解决方案 > 在 Python 中从 CSV 文件创建混合图表

问题描述

我开发了一个 perl 脚本来操作数据并给我一个最终的 csv 文件。不幸的是,我的系统不支持 perl 中的图形和图表包,由于工作限制,我无法安装它们。所以我想尝试获取 csv 文件并在 Python 中组合一些东西来生成一个混合图。我希望第一列是 x 轴上的标签。接下来的三列是条形图。第四列是横过 x 轴的线。

这是示例数据:

Name      PreviousWeekProg     CurrentWeekProg     ExpectedProg     Target
Dan              94                   92                 95           94
Jarrod           34                   56                 60           94
Chris            45                   43                 50           94
Sam              89                   90                 90           94
Aaron            12                   10                 40           94
Jenna            56                   79                 80           94
Eric             90                   45                 90           94

我正在寻找这样的图表: 在此处输入图像描述

我做了一些研究,但和我在 python 中一样一无所知,我想寻求一些关于在 python 中用于混合图表和图形的好模块的指导。对不起,如果我的帖子含糊不清。除了在网上查看其他参考资料外,我对如何去做这件事一无所知。另外,我的 python 版本是 3.8,并且我确实安装了 matplotlib(这是我之前推荐使用的)。

标签: pythonmatplotlibgraphcharts

解决方案


由于@ShaunLowis的答案不包括一个完整的例子,我想我会添加一个。就阅读.csv文件而言,在这种情况下最好的方法可能是使用pandas.read_csv()其他答案指出的。在此示例中,我已命名文件test.csv并将其放置在运行脚本的同一目录中

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

df = pd.read_csv("./test.csv")
names = df['Name'].values
x = np.arange(len(names))
w = 0.3
plt.bar(x-w, df['PreviousWeekProg'].values, width=w, label='PreviousWeekProg')
plt.bar(x, df['CurrentWeekProg'].values, width=w, label='CurrentWeekProg')
plt.bar(x+w, df['ExpectedProg'].values, width=w, label='ExpectedProg')
plt.plot(x, df['Target'].values, lw=2, label='Target')
plt.xticks(x, names)
plt.ylim([0,100])
plt.tight_layout()
plt.xlabel('X label')
plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1), fancybox=True, ncol=5)
plt.savefig("CSVBarplots.png", bbox_inches="tight")
plt.show()

在此处输入图像描述


解释

pandas文档中read_csv()(排除的示例无关的参数),

pandas.read_csv(filepath_or_buffer)

将逗号分隔值 (csv) 文件读入 DataFrame。

filepath_or_buffer: str,路径对象或类文件对象

任何有效的字符串路径都是可接受的。该字符串可以是一个 URL。[...] 如果你想传入一个路径对象,pandas 接受任何os.PathLike.

通过类文件对象,我们指的是具有read()方法的对象,例如文件处理程序(例如通过内置open函数)或StringIO.

在此示例中,我指定了文件的路径,而不是文件对象。

names = df['Name'].values

这会提取'Name'列中的值并将它们转换为numpy.ndarray对象。为了用一个名称绘制多个条形图,我参考了这个答案。然而,为了使用这种方法,我们需要一个与x数组长度相同的浮点数names组,因此

x = np.arange(len(names))

然后设置条的宽度并相应地偏移第一条和第三条,作为参考答案中的轮廓

w = 0.3
plt.bar(x-w, df['PreviousWeekProg'].values, width=w, label='PreviousWeekProg')
plt.bar(x, df['CurrentWeekProg'].values, width=w, label='CurrentWeekProg')
plt.bar(x+w, df['ExpectedProg'].values, width=w, label='ExpectedProg')

matplotlib.pyplot.bar页面(未使用的非位置参数除外),

matplotlib.pyplot.bar(x, height, width=0.8)

条形图位于x[...] 它们的尺寸由width和给出height。、和中

的每一个都可以是应用于所有条的标量,也可以是为每个条提供单独值的长度序列。xheightwidthN

在这种情况下,xheight是值序列(每个柱不同)并且width是标量(每个柱都相同)。

接下来是target非常简单的行,只需将x之前创建的值与'Target'列中的值进行对比

plt.plot(x, df['Target'].values, lw=2, label='Target')

其中lw指定线宽。免责声明:如果每一行的目标值都不相同,.csv这仍然有效,但看起来可能与您想要的不完全一样。

接下来的两行,

plt.xticks(x, names)
plt.ylim([0,100])

只需在条形下方的适当x位置添加名称,然后设置y限制以跨越间隔[0, 100]

这里的最后一点是在情节下方添加图例,

plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05), fancybox=True)

有关如何根据需要进行调整的更多信息,请参阅此答案。


推荐阅读