说明
在当今数据驱动的世界中,可视化或图形确实表达了一个胜过千言万语的故事。可视化提供了快速有效的通信媒体来传达数据,如果与文本或表格共享,则可能难以理解。
虽然有许多强大的可视化工具可用,但有时我们需要一种快速简便的方法来直接在终端中可视化数据。无论我们是远程工作、在服务器上工作,还是只需要与同事共享快速可视化,在终端中绘制图形的能力都非常有用。
让我们看一个简单的示例场景,我正在尝试从我的位置找出 AWS 区域的延迟。我得到了数据,现在想比较一下:
data = [
{
"#": 1,
"AWS Region Name": "US East (N. Virginia)",
"Region Code": "us-east-1",
"Mean": "741 ms",
"Median": "730 ms",
"Min": "723 ms",
"Max": "780 ms",
},
{
"#": 2,
"AWS Region Name": "US East (Ohio)",
"Region Code": "us-east-2",
"Mean": "525 ms",
"Median": "530 ms",
"Min": "244 ms",
"Max": "797 ms",
},
{
"#": 3,
"AWS Region Name": "US West (N. California)",
"Region Code": "us-west-1",
"Mean": "540 ms",
"Median": "535 ms",
"Min": "270 ms",
"Max": "819 ms",
},
{
"#": 4,
"AWS Region Name": "US West (Oregon)",
"Region Code": "us-west-2",
"Mean": "602 ms",
"Median": "594 ms",
"Min": "299 ms",
"Max": "923 ms",
},
{
"#": 5,
"AWS Region Name": "Africa (Cape Town)",
"Region Code": "af-south-1",
"Mean": "632 ms",
"Median": "627 ms",
"Min": "320 ms",
"Max": "953 ms",
},
{
"#": 6,
"AWS Region Name": "Asia Pacific (Melbourne)",
"Region Code": "ap-southeast-4",
"Mean": "599 ms",
"Median": "598 ms",
"Min": "296 ms",
"Max": "905 ms",
},
{
"#": 7,
"AWS Region Name": "Asia Pacific (Hong Kong)",
"Region Code": "ap-east-1",
"Mean": "362 ms",
"Median": "361 ms",
"Min": "353 ms",
"Max": "374 ms",
},
]
print("\nAWS Ping Test results: ")
print("=========================")
for d in data:
print(d["Region Code"], "\t", d["Mean"])
print("\nAWS Ping Test results: ")
print("=========================")
for d in data:
ms = int(d["Mean"].replace(" ms", ""))
ms_bar = round(ms / 10)
print(d["Region Code"], "\t", "*" * ms_bar)
输出如下:
如果我们快速浏览一下,尽管两个表都为我们提供了相似的信息,但很容易在条形图中找到最低的延迟。从这个快速演示中,我们实际上可以看到这种 CLI 可视化的有用性。
现在在某些情况下,绘制此类图形的快速辅助函数可能比导入外部模块更有用和高效。我们还将探索外部模块,但让我们先自己做!
def draw_bar(value, legend=None, char="❚"):
if legend:
print(legend, "\t", char * value)
else:
print(char * value)
print("\nAWS Ping Test results: ")
print("=========================")
for d in data:
print(d["Region Code"], "\t", d["Mean"])
print("\nAWS Ping Test results: ")
print("=========================")
for d in data:
ms = int(d["Mean"].replace(" ms", ""))
ms_bar = round(ms / 10)
# print(d["Region Code"], "\t", "*" * ms_bar)
draw_bar(ms_bar, d["Region Code"])
draw_bar(ms_bar, d["Region Code"], "☐")
draw_bar(ms_bar, d["Region Code"], "░")
在这里,我添加了一个简单的函数来绘制条形图,并使用了一些 Unicode 字符使图形比我们之前的示例更有趣和美观一些
通过提供您自己的 Unicode 字符,可以根据您自己的选择或口味轻松更改(我的不是很好!证据在图片😂中)
虽然一个简单的函数在这种情况下可能会有所帮助,但是,如果你的脚本需要更好的可视化,有一些非常好的外部模块,让我们探索一下这些,我已经在我的项目中使用了其中一些。
1. 终端图
终端图是对于简单散点图非常有用的模块之一。它非常易于使用,只需几行代码即可添加到脚本中。
from terminalplot import plot
x = range(0, 100, 2)
y = [i**2 for i in x]
plot(x, y)
这将导致以下结果:
非常易于使用的模块的代价是不是很灵活,情节字符不可自定义,会打印“*”。此外,没有显示标签或绘图图例的选项。因此,如果您需要一个快速的解决方案来绘制任何类型的数学表达式,而无需非常微小的分辨率,那么它非常适合此目的
2.Asciichartpy
这是 NPM 模块的 Python 移植版本,名称为 asciichart。这个我在我的一个项目中使用了这个模块pynetmon,如果你更感兴趣,你可以在这里阅读它,了解我如何在项目中使用它。
回到模块,虽然 Python 的文档有点缺失,但它与 NodeJS 版本非常相似,所以很容易使用,让我们看一个例子:
import asciichartpy as acp
from random import randint
x = [randint(0, 10) for _ in range(100)]
print(acp.plot(x))
这将生成以下图表:
这在需要绘制流数据的地方非常有用,这就是为什么我在pynetmon项目中使用它来绘制网络接口上的入口和出口数据。您还可以提供一些配置来自定义显示的单位或文本格式,以及一些可供探索或试验的更多选项。如果您正在构建基于文本的用户界面,它非常适合富库或文本库。
3. Termplot
术语图类似于上面提到的终端图,但在自定义不同的绘图类型方面几乎没有更多的灵活性。
import math
from termplot import Plot
xvals, yvals = [], []
for i in range(0, 2000, 5):
xx = i / 100.0
xvals.append(xx)
yvals.append(math.sin(xx) * float(i ** 0.5))
Plot(xvals, yvals, LINE)
这将产生以下散点图
来源: GitHub - justnoise/termplot: Plot data in your terminal
4. 术语图
在这种情况下,如果您需要在终端中为任何类型的财务仪表板绘制烛台图,则此模块很有帮助。它只做一种类型的绘图,但使用 Unicode 字符集绘制烛台图确实令人印象深刻。它不是 pip 可安装的,并且有一个同名的 pip 模块,所以要小心歧义,现在您只能通过将源克隆到您的项目中来使用它。
下面是一个从Windows终端上的CSV数据呈现OHLC图表的示例Termgraph:
终端上的术语图OHLC!
5. 剧情
Plotile使用了一种非常酷的方法,使用盲文点来打印一些非常好的分辨率图表。与上面提到的其他模块相比,这是相对较新的模块之一。我实际上正在考虑将 Plotile 与 asciichart 交换为 pynetmon 图。
它非常易于使用并集成到任何脚本中,让我们检查一个例子:
import plotille
import psutil
temps = []
n = []
for i in range(100):
n.append(i)
temps.append(psutil.cpu_percent(interval=0.1))
fig = plotille.Figure()
print(plotille.plot(n, temps, height=30, width=60, interp="linear", lc="cyan"))
在示例中,我每 0.1 秒将系统的 CPU 使用率存储到一个列表中,这是为了在实际应用程序中简单起见,我们可能会实时执行此操作,但现在让我们检查结果:
如您所见,图形分辨率更精确,美观性更好,该模块也易于定制,因此您可以轻松更改线条颜色、背景等。
在示例中,我只使用了一个简单的图,也有散点图或直方图可用。此外,如果您需要可以通过操作 Canvas 来完成的自定义图形。甚至图像也可以在 Canvas 中渲染,如下所示
来源:剧情示例
很酷不是吗,如果您对ASCII艺术感兴趣,还可以实现很多可能性。
6. 术语图
到目前为止讨论的库的常见模式主要限于线图、条形图和散点图。但是,如果您需要绘制一个漂亮的饼图或圆环图,(是的,那些通常来自冗长而无聊会议的商业演示的循环内容可以很容易地通过电子邮件传达,但是嘿,这很有趣,让我们邀请所有人并浪费 30 分钟的时间,最终🤣一无所获,对不起咆哮, 但你明白了要点。
现在的TLDR;术语图允许您在终端中打印饼图和圆环图,默认情况下使用冷色组合。
对于我们的示例,让我们绘制我全天的精彩时间表:
import termcharts
from rich import print
from rich.layout import Layout
from rich.panel import Panel
data = {"Work": 8, "Sleep": 6, "Gaming": 4, "Netflix": 4, "Misc": 2}
chart1 = termcharts.bar(data, title="Time of my life", rich=True)
chart2 = termcharts.bar(data, title="Time of my life", mode="v", rich=True) # vertical
chart_pie = termcharts.pie(data, title="Time of my life", rich=True)
chart_donut = termcharts.doughnut(data, title="Time of my life", rich=True)
layout = Layout()
layout.split_column(Layout(name="upper"), Layout(name="lower"))
layout["upper"].split_row(
Layout(name="uleft"),
Layout(name="uright"),
)
layout["lower"].split_row(
Layout(name="lleft"),
Layout(name="lright"),
)
layout["uleft"].update(Panel(chart1))
layout["uright"].update(Panel(chart2))
layout["lleft"].update(Panel(chart_pie))
layout["lright"].update(Panel(chart_donut))
print(layout)
这将导致以下结果(免责声明我远未达到这种生产力水平或调度😆,这只是为了演示目的,死星也不是图表的一部分,只是我的终端背景。
如果需要,此模块可以很好地添加到需要此类图表在终端上呈现的任何类型的仪表板。
7. 正文
到目前为止,Plotext可能是我们在本文中讨论的最通用的模块(我将其保存到最后一个,真是巧合! 💡Plotext支持大多数类型的图表,包括散点图,折线图,条形图,直方图,日期时间(时间序列),烛台一些特殊类型的图表,如误差图,混淆矩阵,事件时间线等。它可以显示图像和gif,不仅可以在终端上播放视频,还可以直接从youtube播放!
是时候举一些例子了,让我们先尝试一下烛台图,我们之前用termgraph做过一个,但我个人认为plotext分辨率要好一些。
import plotext as plt
import yfinance as yf
plt.date_form("d/m/Y")
start = plt.string_to_datetime("01/01/2023")
end = plt.today_datetime()
data = yf.download("SPY", start, end)
dates = plt.datetimes_to_string(data.index)
plt.clf()
plt.theme("dark")
plt.candlestick(dates, data)
plt.title("SPY Stock Price CandleSticks")
plt.show()
我已将主题更改为黑暗模式,以便黑暗面拥抱者不会灼伤他们的眼睛!默认主题是白色的,类似于我们过去在 matplotlib 图表中看到的主题。蜡烛图如下所示:
图谱烛台图表
对于视频演示,我将使用每个人一直以来最喜欢的视频,您很快就会看到!
import plotext as plt
src = "./Rick_Astley_Never_Gonna_Give_You_Up.mp4"
plt.play_video(src, from_youtube=True)
Plotext提到它可以直接播放来自Youtube的视频,但是当我尝试时,我无法播放它,并且弹出了很多依赖项问题,所以我使用了本地视频文件。
Rick Rolling 在 Windows 终端上通过 Plotext
所以现在我们也可以在航站楼享受里克·阿什利!如果删除或设置为 False,则需要播放音频,只有视频将在没有音频的情况下播放。from_youtube=True
就是这样,我分享了 7 个很酷的模块,您可以将这些模块集成到您的下一个终端脚本或项目中,使它们看起来令人惊叹!
如果您喜欢这篇文章并希望支持或鼓励我,请随时关注我或订阅我的时事通讯或在Twitter上关注我。
另外,如果你想支持我未来的博客努力,你可以给我买咖啡!