BNU-FZH

fengzhenhua@outlook.com

Node.js 是一个流行的服务器端 JavaScript 运行时环境,用于构建高性能、可扩展的网络应用程序。Node.js 有两个主要的版本发布频道,分别是 Current 版本和 LTS 版本,它们之间有一些重要的区别。在本文中,我将详细介绍 Node.jsCurrent 版本和 LTS 版本的区别,并通过示例来说明这些区别。

Node.js 的版本发布周期

首先,让我们了解一下 Node.js 的版本发布周期,以便更好地理解 Current 版本和 LTS 版本之间的差异。

  • Current 版本:Current 版本是 Node.js 的最新开发版本,通常每隔几个月发布一次。它包含最新的功能、改进和实验性特性,但不太稳定。Current 版本的目标是提供给开发人员一个平台来尝试新的功能和实验性特性,以便反馈和测试。
  • LTS 版本:LTS(Long-Term Support)版本是 Node.js 的长期支持版本,通常每隔两年发布一次。LTS 版本的主要特点是稳定性和可靠性。它们接受持续的维护和安全更新,以确保企业和生产环境的稳定性。

区别一:稳定性和可靠性

最明显的区别是 Current 版本和 LTS 版本的稳定性和可靠性。LTS 版本在发布后会接受长达几年的维护和安全更新,因此非常适合用于生产环境,特别是对于企业应用程序。相比之下,Current 版本可能包含实验性特性和较新的代码,可能会引入不稳定性或潜在的问题,因此不建议在生产环境中使用。

示例:假设你正在开发一个在线电子商务网站,该网站需要高度稳定性和可靠性。在这种情况下,你可能会选择使用 LTS 版本,因为它提供了经过验证的稳定性和长期支持,有助于确保你的网站在生产环境中保持高可用性。另一方面,如果你正在开发一个实验性的新功能,可以选择 Current 版本,以便尝试最新的功能和改进。

区别二:新特性和改进

Current 版本是 Node.js 的最新开发版本,因此包含了最新的功能、改进和实验性特性。这使得它成为了尝试新技术和构建原型的理想选择。如果你想要访问最新的 ECMAScript 版本、Node.js API 或其他功能,Current 版本可能会更适合你。

示例:假设你需要使用最新的 ECMAScript 模块系统,以便更好地组织你的代码。在这种情况下,你可以选择 Current 版本,因为它可能会提供对这些新特性的更好支持。另外,如果你想尝试 Node.js 中的实验性功能,例如 Web Streams API,也可以选择 Current 版本来体验这些新功能。

区别三:性能优化

Current 版本通常包含了性能优化和改进,以提高应用程序的性能。这些优化可以包括更快的执行速度、更低的内存消耗和更好的并发处理能力。如果你对应用程序的性能有较高的要求,那么可能会考虑使用 Current 版本来获得这些优势。

示例:假设你正在开发一个实时多人游戏服务器,需要处理大量并发连接和快速响应时间。在这种情况下,你可能会选择 Current 版本,因为它可能包含了性能改进,有助于提高服务器的响应速度和并发处理能力,从而提供更好的游戏体验。

区别四:维护和安全更新

LTS 版本的一个关键优势是它们接受长期的维护和安全更新。这意味着即使在发布后的几年内,Node.js 社区仍然会修复潜在的安全漏洞和问题,以确保应用程序的安全性。对于企业和生产环境来说,这是一个非常重要的因素。

示例:假设你的公司运行着一个在线支付平台,处理大量敏感用户数据。在这种情况下,安全性至关重要。你可能会选择 LTS 版本,因为它提供了长期的维护和安全更新,帮助你保持应用程序的安全性,同时避免潜在的安全威胁。

区别五:社区支持

由于 LTS 版本在生命周期内接受长期的维护,因此通常拥有更广泛的社区支持。这意味着你可以更容易地找到解决问题的资源、文档和社区支持。相比之下,Current 版本可能会更加小众,社区支持可能有限。

示例:假设你在开发过程中遇到了一个复杂的问题,需要寻求帮助和支持。如果你使用的是 LTS 版本,你可能会更容易地在社区中找到有经验的开发者来帮助你解决问题,因为这个版本有更广泛的社区支持。

区别六:升级频率

LTS

本的升级频率较低,通常每隔两年发布一个新的 LTS 版本。这使得企业可以更轻松地规划和管理升级过程。相比之下,Current 版本的升级频率较高,可能每隔几个月就会发布一个新版本,需要更频繁的升级和迁移工作。

示例:如果你的公司有一个严格的升级策略,并且希望最小化升级带来的风险和工作量,那么你可能会更倾向于选择 LTS 版本。这样,你可以更轻松地规划升级,并确保稳定性和可靠性。

如何选择适合的版本?

选择 Node.js 的版本取决于你的具体需求和项目的性质。以下是一些指导原则,帮助你决定是使用 Current 版本还是 LTS 版本:

  1. 生产环境 vs. 开发环境:如果你的应用程序将在生产环境中运行,特别是对于企业级应用程序,通常建议使用 LTS 版本,以确保稳定性和安全性。对于开发和测试环境,你可以考虑使用 Current 版本来尝试最新的功能和改进。
  2. 功能需求:如果你需要访问最新的 ECMAScript 版本、Node.js API 或其他功能,Current 版本可能更适合你。如果你的应用程序对稳定性要求较高,那么应该优先选择 LTS 版本。
  3. 性能需求:如果你对应用程序的性能有较高的要求,可以考虑使用 Current 版本,因为它可能包含性能优化。但要确保你有充分的测试和性能监控,以确保新版本不会引入性能问题。
  4. 安全性:如果你处理敏感数据或对安全性有严格要求,LTS 版本是更安全的选择,因为它接受长期的维护和安全更新。
  5. 社区支持:如果你需要广泛的社区支持,特别是在解决问题时,LTS 版本通常会有更多的资源和支持可用。
  6. 升级策略:考虑你的公司或项目的升级策略。如果你希望最小化升级工作量,LTS 版本可能更适合你。

结论

Node.jsCurrent 版本和 LTS 版本之间存在明显的区别,涵盖了稳定性、新特性、性能、维护、社区支持和升级频率等方面。在选择适合你的版本时,需要综合考虑你的项目需求和优先级。无论你选择哪个版本,都要确保了解该版本的特性和限制,并采取适当的测试和监控措施,以确保应用程序的稳定性和性能。在任何情况下,Node.js 的强大生态系统和活跃的社区都将为你提供支持和资源,帮助你构建出色的应用程序。

很多人觉得内存频率越高速度越快,尤其是在英特尔12代酷睿处理器支持DDR5之后,不少人都想升级到DDR5,以为升级到DDR5就能获得更高的性能。事实真的是这样吗?如下图两内存,都是同样的芝奇的DDR4 3600MHz 16GBx2的内存,为什么会有500+的价格差?因为它们有不同的CL时序,一个是18-22-22-42,另一个是16-19-19-39,这点区别就值500+。那么内存CL时序到底是什么?对性能又有什么影响?

内存在存取数据时是以行列的方式进行,跟Excel表格类似,通过行列的方式定位数据。内存时序代表的是行列访问所需要的周期数(周期数不等于时间),主要有四个分别是CL,tRCD,tRP,tRAS。CL代表内存访问一次列所需的周期数,下图为16,tRCD表示内存访问一次行所需的最小周期数,下图中的19,tRP表示打开下一行的最小周期数,下图中为19,tRAS代表的是行活动到发出打开下一行的最小周期数。看起来很复杂,最重要的就是第一个,即CL。

CL全称CAS latency,内存访问一次列的延迟时间,在频率相同的情况下,CL值越小内存速度越快。就跟我们看小说一样,只要定位到了行,剩下的就是读行中的每一列,直到读完一行才会读下一行。内存只要定位到了数据所在的行,剩下的基本就是列操作,直到读完一行才会进行一次行操作。所以CL值对内存来说非常重要。

从下表中可以发现CL(表中的CAS Latency)的值是随着内存频率的增加而增大的。DDR5 4800MHz的CL值为40个时钟周期,比DDR4更大。这也是为什么DDR5比DDR4提升不大的原因,频率高了延迟更大。由于CL是时钟周期与内存频率相关不好比较,所以要换成时间。CL延迟时时间=1/(DDR频率/2)* CL周期数*1000。

公式中的1代表1秒钟,内存频率除以2,是因为DDR的全称是Double Data Rate即双倍数据传输速率,如下图SDR不用除,QDR要除以4才是内存的时钟频率,因此上图的DDR4,DDR5都要除以2 。乘1000是为了把微秒换成纳秒。所以上图DDR5 4800MHz的CL延迟时间=1/(4800/2)*40*1000=16.67ns。

内存的CL,tRCD等都是可以通过BIOS修改的,如下图修改成1600MHz 16CL和1500MHz 15CL哪个更快?用上面的公式算CL延迟都是10ns,所以几乎一样快。决定内存速度的除了CL延迟以外,还有其它几个。但CL影响更大。

现在我们来解决第一张图为什么后者比前者更贵的问题。2099的CL延迟时间为8.89ns,而1549的CL延迟时间为10ns,2099的存取速度更快,也因此更贵。

引用:对内存频率的误解!以为频率越高速度就越快,真相未必是这样

问题描述

今天突然发现台式机上的蓝牙无法启动,按钮开启后蓝牙仍然处于关闭状态。如图所示:

蓝牙无法打开

解决方案

1. 卸载并重新加载btusb内核模块(支持蓝牙设备的内核模块)

1
2
3
4
sudo rmmod btintel
sudo rmmod btusb
sudo modprobe btusb
sudo modprobe btintel

2024年08月29日升级ArchLinux后发现蓝牙再次无法打开,根据文章在Archlinux 下蓝牙突然无法打开的解决办法 修复此问题,于是做出如上修改。

2. 安装蓝牙工具和工具包

1
sudo pacman -S --needed --noconfirm bluez bluez-utils pipewire-pulse bluedevil blueman

3. 启动蓝牙服务

1
sudo service bluetooth start

4. 重新解除蓝牙设备的阻止

1
2
rfkill block bluetooth
rfkill unblock bluetooth

蓝牙设备可被检测到

蓝牙启动成功

收音机并未随着互联网时代的到来而消失,而是以互联网广播的形式继续存在,并且变得更加丰富。互联网广播除了传统的直播电台内容外,还有大量的自制节目,可供听众随意的点播、订阅,比如蜻蜓 FM、喜马拉雅等。

今天要介绍的是 Linux 下最优秀的在线广播收音机软件 Shortwave。使用 Shortwave 可以无限制收听世界各地的高品质广播电台,尤其是大量的音乐台、外语广播。

Shortwave

Shortwave 官方网站:https://www.shortwave.com, WindowsIOSAndroid用户请前往官方网站下载安装包安装。

ArchLinux 并没有将shortwave收录到官方仓库,用户可以使用paruyay安装

1
paru -S --noconfirm shortwave

LinuxMint 用户可以在软件中心(软件管理器)中搜索安装即可。

启动 Shortwave,界面简洁,没有任何复杂的设置,甚至可以说,没有设置。主界面罗列了各种流行电台,顶部一个搜索栏。

随便点击一个电台,即可播放。虽然是国外电台,但相应速度不错,也不会卡顿。

对于喜欢的电台可以点击电台详情,然后“添加到库”进行收藏。这个 Dance Wave 是以 DJ 动感舞曲为主的电台。

Music Lake 以纯净、轻音乐为主;Radio Paradise 则是320k高品质的音乐节目,音质很棒。

Shortwave 除了罗列各种流行电台,也可以搜索。如图所示,搜索美国知音的电台结果。想 1990 年代末、2000 年代初,薄荷君在高中、大学时期,经常用那嘈杂不堪、信号不稳的收音机,左右摇摆天线,收听 VOA Special English 慢速英语。

Shortwave 还可以缩小成 Mini 播放器模式。

如前所述,Shortwave 没有什么设置选项,只有一个关闭/打开消息通知。够简单易用吧?

众所周知在Windows下修改U盘的名称是相当简单的,但是查询Linux下修改U盘名称,搜到的教程都十分麻烦。本文给出一个比较简单的方法,就是借助磁盘工具Gparted修改,因为修改U盘名称毕竟是小概率事件,所以此操作简单易行。

  • Gnarted没有安装,则先安装命令:

    1
    sudo pacman -S gparted

  • 插入待修改名称的U盘

  • 点击右上角,选中待修改名称的U盘

选中待修改名称的U盘
  • 右键,选择卸载(U)
卸载挂载的U盘
  • 右键,选择文件系统卷标(L)
选中文件系统卷标
  • 在弹出的对话框输入新的U盘名称, 然后点上面的符号√应用全部操作, 修改名称完毕
应用修改

近期由于我的U盘仓库BNU-FZHU盘损坏,所以不得不升级zugit.sh脚本, 添加一键搬家功能,这可以方便的将仓库同步到新的U盘. 然而在更新后将新版本的zugit.sh推送到gitee时,发现报错:

推送至Gitee报错

看日志报出的错误,It is required that your private key files are NOT accessible by others,翻译就是需要私钥文件不能被其他人所访问。私钥是访问linux服务器的凭证,如果被别人获取到,就可能对服务器安全造成影响,这可能也就是这个问题的初衷吧。

按照错误提示,该文件不能被其他人访问,只要将所属组和其他人的read权限取消即可. 于是将Gitee对使用的ssh密钥~/.ssh/id_ed25519_1更改权限为600,即

1
chmod 600 ~/.ssh/id_ed25519_1

方式一:远程仓库没有文件

1
2
3
4
5
git init(初始化git仓库);
git remote add 地址(设置remote地址);
git add . (将所有变更提交到本地仓库);
git commit -m '' (提交注释);
git push(本地仓库推送到远程仓库)

方式二:远程仓库有文件

1
2
3
4
5
6
7
git init(初始化git仓库);
git remote add origin 地址(设置远程remote地址);
git pull origin master(拉取远程仓库master的文件)
git branch --set-upstream-to=origin/master master(将本地master设置为远程master分支)
git add . (将所有变更提交到本地仓库);
git commit -m '' (提交注释);
git push

方式三:

1
2
3
4
5
git clone 地址(克隆远程仓库) test
cp -r 项目文件 test
git add . (将所有变更提交到本地仓库);
git commit -m '' (提交注释);
git push

设置用户和邮箱

一:全局

1
2
git config --global user.name "you name"
git config --global user.email "you email"

二:局部(单个项目)

1
2
git config user.name "you name"
git config user.email "you email"

强制推送

1
git push -f

APIApplication Programming Interface, 应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。 ——百度百科(应用程序编程接口播报)

API 的工作原理是什么?

通过 API,您无需了解实施原理,也能将您的产品或服务与其他的互通。这样可以简化应用的开发,节省时间和成本。在您开发新的工具和产品,或管理现有工具和产品时,强大灵活的 API 可以帮助您简化设计、管理和使用,并带来更多创新机遇。

API 有时被视为合同,而合同文本则代表了各方之间的协议:如果一方以特定方式发送远程请求,该协议规定了另一方的软件将如何做出响应。

由于 API 简化了开发人员将新应用组件集成到现有基础架构中的方式,继而也对业务和 IT 团队之间的协作提供了帮助。随着数字市场日新月异,业务需求通常也会出现迅速变化,新的竞争对手利用新的应用即可改变整个行业。为了保持竞争力,支持快速开发和部署创新服务尤为重要。云原生应用开发是提高开发速度的一个明确办法,依赖于通过 API 连接微服务应用架构。

API 是通过云原生应用开发来连接您自己的基础架构的一个简化方式,此外还支持您向客户和其他外部用户分享您的数据。公共 API 有着独特的商业价值,因其可以简化和扩展您与合作伙伴的联系方式,并有望支持您从数据中实现盈利(Google Maps API 便是其中一个广为人知的案例)。

API的工作原理

例如,我们假设有这样一家图书发行公司:该发行商可以提供一个云应用,供书店店员查看书的库存情况。这款应用的开发成本高昂、有平台限制、开发周期较长,还需进行日常维护。

或者,该发行商也可以提供一个 API 来查询库存情况。这一方法有以下几个好处:

  • API 可以帮助他们将所有库存相关信息汇集到一处,供客户方便地访问数据。
  • 只要 API 的行为不发生变化,该图书发行商就能在不影响客户的情况下更改内部系统。
  • 借助公开可用的 API,开发人员可为该图书发行商、图书销售商或第三方开发一个应用,帮助客户查找所需的图书。这样不仅能提高销量,还能带来其他的商机。

简而言之,API 既能让您开放自己的资源访问权限,又能确保安全性并让您继续握有控制权。如何以及向谁开放访问权限由您自己决定。API 安全防护离不开良好的 API 管理,其中包括对 API 网关的使用。借助通联各种资源(包括传统系统和物联网,IoT)的分布式集成平台,您可以连接至 API 并创建使用 API 提供的数据或功能的应用。

API 发行政策

私有

这类 API 仅供内部使用,能让公司最大限度地控制自己的 API。

合作伙伴

您会和特定的业务合作伙伴共享这类 API。它能在不影响质量的情况下带来额外收益。

公共

这类 API 可供所有人使用。第三方可以使用这类 API 来开发应用,以便与您的 API 进行互动或实现某种创新。

如何利用 API 实现创新?

通过向合作伙伴或公众提供您的 API,可以:

  • 创造新的收入渠道,或拓展现有收入渠道。
  • 扩大您的品牌覆盖范围。
  • 通过外部开发和协作,推动开放创新或提高效率。

听上去还不错,对吗?但是,API 是如何做到上述几点的呢?

我们继续以刚才的那个图书发行公司为例。

假设该公司的某个合作伙伴开发了一个应用,可以帮助人们查找书店书架上的图书。这种体验的改进为书店带来了更多的客户(该发行商的客户),并拓展了现有的收入渠道。

或许会有第三方使用某个公共 API 来开发应用,以便人们直接从该发行商处(而非书店)购书。这样就能为该图书发行商打开新的收入渠道。

与特定合作伙伴或全世界共享 API 能带来积极的影响。除了自己公司的营销活动之外,每一个合作关系都能帮助您提高品牌辨识度。以公共 API 的形式向所有人开放技术,可以激励开发人员以您的 API 为中心构建应用生态系统。有更多的人使用您的技术,就意味着可能会有更多的人与您做生意。

公开技术可以带来意外之喜。有时,这些惊喜更会颠覆整个行业。对于这家图书发行公司而言,新形态的公司(比如图书出借服务)可能会完全改变他们的业务模式。借助合作伙伴和公共 API,您可以激发社区成员的创意(其人数远超您的内部开发团队)。各种奇思妙想会源源不断地涌现,公司只需明辨市场的变化情况并做好相应的准备。API 大有用处。

API 简史

API 概念的出现,始于计算机时代的初期,远远早于个人电脑诞生之前。当时,API 常被当作操作系统的库,而且基本上都在本地系统上运行,仅偶尔用于大型机之间传递消息。将近 30 年后,API 走出了它们的本地环境。到了 21 世纪初,API 成为了用于实现数据远程集成的一种重要技术。

远程 API

远程 API 旨在通过通信网络进行互动。这里的_远程_是指 API 操控的资源不在提出请求的计算机上。由于互联网是应用最广泛的通信网络,所以大多数 API 都是基于 Web 标准来设计的。并非所有的远程 API 都是 Web API,但可以认为 Web API 都是远程 API。

Web API 通常会使用 HTTP 来传输请求消息,并提供响应消息的结构定义。这些响应消息通常都会以 XML 或 JSON 文件的形式来提供。XML 和 JSON 都是首选格式,因为它们会以易于其他应用操纵的方式来呈现数据。

SOAP 和 REST

随着 Web API 的不断普及,相应的协议规范也随之产生了,从而推动了信息交换的标准化:简单对象访问协议,简称 SOAP。使用 SOAP 设计的 API 会使用 XML 格式来收发消息,并通过 HTTP 或 SMTP 来接收请求。使用 SOAP 时,在不同环境中运行的应用或使用不同语言编写的应用能够更加轻松地共享信息。

相关的规范还有一个,即表述性状态传递(REST)。遵循 REST 架构约束的 Web API 被称为 RESTful API。REST 与 SOAP 有着根本区别:SOAP 是一种协议,而 REST 是一种架构风格。这意味着 RESTful Web API 没有官方标准。正如 Roy Fielding 在论文“Architectural Styles and the Design of Network-based Software Architectures”(架构模式以及基于网络的软件架构的设计)中定义的那样,只要 API 符合 RESTful 系统的 6 个导向性约束,就算作 RESTful API:

  • 客户端/服务器架构:REST 架构由客户端、服务器和资源构成,通过 HTTP 来处理请求。
  • 无状态:请求所经过的服务器上不会存储任何客户端内容。与会话状态相关的信息会存储在客户端上。
  • 可缓存性:通过缓存,可免去客户端与服务器之间的某些交互。
  • 分层系统:客户机与服务器之间的交互可以通过额外的层来进行调解。这些层可以提供额外的功能,如负载均衡、共享缓存或安全防护。
  • 按需代码(可选):服务器可通过传输可执行代码来扩展客户端的功能。
  • 统一接口:这项约束是 RESTful API 的设计核心,共涵盖 4 个层面:
    • 识别请求中的资源:请求中的资源会被识别,并与返回给客户端的表示内容分离开来。
    • 通过不同的表示内容来操纵资源:客户端会收到表示不同资源的文件。这些表示内容必须提供足够的信息,以便执行修改或删除操作。
    • 自描述消息:返回给客户端的每个消息都包含充足的信息,用于指明客户端应该如何处理所收到的信息。
    • 将超媒体作为应用状态的引擎:在访问某个资源后,REST 客户端应该能够通过超链接来发现当前可用的所有其他操作。

虽然看似有很多约束需要遵循,但是这些约束遵循起来要比遵循规定的协议容易得多。因此,RESTful API 现在变得比 SOAP 更为普及。

近年来,OpenAPI 规范已发展成为定义 REST API 的通用标准。OpenAPI 为开发人员提供了一种与语言无关的方式来构建 REST API 接口,从而最大程度减少不确定的因素,让用户安心工作。

另一个新兴的 API 标准是 GraphQL,这是一种可替代 REST 的查询语言和服务器端运行时。GraphQL 可优先让客户端准确地获得所需的数据,没有任何冗多余。作为 REST 的替代方案,GraphQL 允许开发人员构建相应的请求,从而通过单个 API 调用从多个数据源中提取数据。

SOA 与微服务架构

最常使用远程 API 的 2 种架构方案分别是:面向服务的架构(SOA)和微服务架构。在这 2 种方案中,SOA 的历史更为久远一些。最初,它是在单体式应用的基础上经过改进而形成的。虽然单个单体式应用也可以完成各种操作,但通过某种集成模式(如企业服务总线(ESB))在不同应用间实现松散耦合后,即可获得某些功能。

从大多数层面来看,SOA 都要比单体式架构更简单;但是,如果无法明确理解各种组件交互,SOA 也可能会进一步加剧整个环境的复杂性。这种复杂性的加剧会重新引发 SOA 想要解决的某些问题。

对于专用松散耦合服务的使用,微服务架构与 SOA 模式类似。但是,微服务架构会对传统架构进行进一步细分。在微服务架构中,服务会采用通用消息传递框架,如 RESTful API。它们会使用 RESTful API 来实现相互通信,且无需执行繁琐的数据转换处理或使用其他的集成层。使用 RESTful API 可以加速新功能和新更新的交付;甚至还可以说,是这类 API 促进了这种速度的提升。该架构中的每一个服务都呈离散状态。一个服务可以被取代、增强或丢弃,而不会影响架构中的任何其他服务。这种轻量级架构有助于优化分布式资源或云资源,而且能够支持个别服务的动态扩展。

API 和 Webhook

Webhook 是一种基于 HTTP 的回调函数,可在 2 个 API 之间实现轻量级的事件驱动通信。许多种类的应用使用 Webhook 来从其他应用接收少量数据,但 Webhook 也可用于在 GitOps 环境中触发自动化工作流。

Webhook 通常被称为逆向 API 或推送 API,因为它们让通信责任落在了服务器而不是客户端身上。不再是客户端发送 HTTP 请求来索取数据,直到服务器响应为止,而是服务器等到数据可用时向客户端发送一个 HTTP POST 请求。虽然有这样的昵称,但 Webhook 不是 API;两者相互配合。应用必须具有 API 才能使用 Webhook。

简介

Veusz是一个具有用户界面的科研绘图集成软件,能够绘制符合出版要求的2D3D可视化图表。其能够在WindowsLinux/UnixmacOS上运行,支持矢量和位图结果输出,最重要的是Veusz是一款免费软件,Veusz支持从文本、CSVHDF5FITS文件格式中导入数据,更多关于Veusz的介绍可参考:Veusz官网

Veusz操作界面

绘图教程

如何绘制高质量的科学图表

绘制科学图表有很多技巧,本部分将介绍几个小技巧:

  • 图表的标题要简洁明了,能够清晰地表达图表的主题和目的。
  • 使用合适的颜色和字体,避免过度花哨或冗杂的设计。
  • 在图例中使用相同的颜色和线型,使其易于阅读和理解。
  • 使用清晰的坐标轴标签和单位。
  • 在图表中突出显示关键数据和结果。

通过上述技巧和 veusz 工具,可以轻松地制作出高质量的科学图表,在科学研究和学术交流中发挥重要的作用。

在数据可视化领域,Matplotlib是Python中最常用的绘图库之一。既然它被用于数据可视化,那么从图中提取数据也是Matplotlib的一个重要应用场景。在本文中,我们将介绍如何使用Matplotlib从图中提取数据并利用这些数据进行进一步的处理。

一个简单实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import matplotlib.pyplot as plt

# 生成500个0~1之间的随机数作为x轴数据
x = np.random.rand(500)
# 生成与x轴数据数量相同的随机数作为y轴数据
y = np.random.rand(500)

# 绘制散点图
plt.scatter(x, y)

# 设置横轴标签和纵轴标签
plt.xlabel("x")
plt.ylabel("y")

# 设置图表的标题
plt.title("Scatter Plot")

# 显示图表
plt.show()

上述代码通过numpy库生成了5000~1之间的随机数,并将这些随机数分别作为x轴y轴的数据,最终绘制出了一个散点图。其中,plt.scatter()函数是用于绘制散点图的函数,plt.xlabel()plt.ylabel()函数是用于设置横轴标签和纵轴标签的函数,plt.title()函数是用于设置图表标题的函数。

如何从Matplotlib图中提取数据

在Matplotlib中,要提取图中的数据,最常见的方式是获取图中的Artist对象,然后从这些对象中获取数据。Artist是所有绘图元素的基类,包括坐标轴、文字、点、线等。因此,从Artist对象中获取数据可以获取到图表中所有的信息。

获取散点图的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

# 生成500个0~1之间的随机数作为x轴数据
x = np.random.rand(500)
# 生成与x轴数据数量相同的随机数作为y轴数据
y = np.random.rand(500)

# 绘制散点图
plt.scatter(x, y)

# 获取散点图的Artist对象
scatter_plot = plt.gca().collections[0]

# 打印每个散点的x轴坐标和y轴坐标
for i in range(len(scatter_plot._offsets)):
print("x: ", scatter_plot._offsets[i][0], "y: ", scatter_plot._offsets[i][1])

上述代码中,plt.gca()函数返回当前的Axes对象,我们通过对这个对象调用collections属性获取到了散点图的Artist对象。获取到这个对象后,我们可以从_offsets属性中获取到每个散点的坐标信息。上述代码中使用了一个for循环打印出了每个散点的x轴坐标和y轴坐标。

获取拆线图数据

折线图是绘制曲线最常见的方式之一。在Matplotlib中,使用plt.plot()函数可以方便地绘制折线图。为了演示从折线图中获取数据的方法,我们来生成一个简单的折线图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import matplotlib.pyplot as plt

# 生成0~10之间的100个数作为x轴数据
x = np.linspace(0, 10, 100)
# 生成sin函数在0~10之间的值作为y轴数据
y = np.sin(x)

# 绘制折线图
plt.plot(x, y)

# 设置横轴标签和纵轴标签
plt.xlabel("x")
plt.ylabel("y")

# 设置图表的标题
plt.title("Line Plot")

# 显示图表
plt.show()

在得到了折线图之后,我们可以通过如下代码从折线图中获取数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

# 生成0~10之间的100个数作为x轴数据
x = np.linspace(0, 10, 100)
# 生成sin函数在0~10之间的值作为y轴数据
y = np.sin(x)

# 绘制折线图
plt.plot(x, y)

# 获取折线的Artist对象
line_plot = plt.gca().lines[0]

# 打印每个点的x轴坐标和y轴坐标
for i in range(len(line_plot.get_xdata())):
print("x: ", line_plot.get_xdata()[i], "y: ", line_plot.get_ydata()[i])

在上述代码中,plt.gca()函数获取到当前的Axes对象,我们通过对这个对象调用lines属性获取到了折线图的Artist对象。获取到这个对象后,我们可以通过get_xdata()get_ydata()方法获取到折线图上每个点的x轴坐标和y轴坐标。上述代码中使用了一个for循环将获取到的x轴坐标和y轴坐标打印出来。

取柱状图数据

柱状图是绘制分布最常见的方式之一。在Matplotlib中,使用plt.bar()函数可以方便地绘制柱状图。为了演示从柱状图中获取数据的方法,我们来生成一个简单的柱状图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import matplotlib.pyplot as plt

# 生成5个0~1之间的随机数作为x轴数据
x = np.random.rand(5)
# 生成5个0~1之间的随机数作为y轴数据
y = np.random.rand(5)

# 绘制柱状图
plt.bar(x, y)

# 设置横轴标签和纵轴标签
plt.xlabel("x")
plt.ylabel("y")

# 设置图表的标题
plt.title("Bar Plot")

# 显示图表
plt.show()

在得到了柱状图之后,我们可以通过如下代码从柱状图中获取数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

# 生成5个0~1之间的随机数作为x轴数据
x = np.random.rand(5)
# 生成5个0~1之间的随机数作为y轴数据
y = np.random.rand(5)

# 绘制柱状图
plt.bar(x, y)

# 获取柱状图的Artist对象
bar_plot = plt.gca().patches

# 打印每个柱子的x轴坐标和y轴坐标
for i in range(len(bar_plot)):
print("x: ", bar_plot[i].get_x(), "y: ", bar_plot[i].get_height())

在上述代码中,plt.gca()函数获取到当前的Axes对象,我们通过对这个对象调用patches属性获取到了柱状图的Artist对象。获取到这个对象后,我们可以通过get_x()get_height()方法获取到柱状图的每个柱子的x轴坐标和y轴坐标。上述代码中使用了一个for循环将获取到的x轴坐标和y轴坐标打印出来。

总结

本文介绍了如何使用Matplotlib从图中提取数据的方法,包括散点图、折线图和柱状图的例子。通过这些例子,我们可以发现从Matplotlib图中获取数据的办法都是类似的,都是获取到图中的Artist对象,然后从这些对象中获取需要的数据。在实际使用中,我们还可以通过定制Artist对象来控制绘图过程,更好地实现我们的数据可视化需求。