python - 在 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(这是我之前推荐使用的)。
解决方案
由于@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
。、和中
的每一个都可以是应用于所有条的标量,也可以是为每个条提供单独值的长度序列。x
height
width
N
在这种情况下,x
和height
是值序列(每个柱不同)并且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)
有关如何根据需要进行调整的更多信息,请参阅此答案。
推荐阅读
- python - Numpy:在左边的任何东西都是假的地方设置假
- mysql - 移动表数据错误'#1062 - 重复条目'
- haproxy - 如何使用 nifi.web.proxy.host 和 nifi.web.proxy.context.path?
- asp.net - 如何在asp.net mvc5中创建动态角色
- admob - admob中的帐号错误
- ios - 地图上的折线不可见
- data-structures - 为什么优先级队列不能像普通队列一样环绕?
- php - 如何将 opencart 与 Amazon CDN 集成?
- rust - Rust 中的访问者模式
- java - 如何使用java在linux服务器上创建文件