使用Matplotlib画图时如何修改字体及显示汉字


前情提要

Matplotlib是python下一个非常常用的绘图库, 可是如果你用pip install matplotlib默认安装后, 却会发现它会把你输入的中文变成框框.
原因其实很简单, 只是因为默认的Matplotlib安装不带中文字体而已, 所以我们需要将添加中文字体进去.
当然还有可能的原因是你用的是python2, 对于utf-8的中文文本要进行一些别的非常恶心的操作, 当然这个不是本文的讨论范围.
以下文字的操作环境是Windows SubSystem for Linux, 但是原理在各个平台应该是通用的.

如何添加中文字体到Matplotlib中

Matplotlib的字体无论是在Linux还是在Windows中, 都和系统字体是完全独立的, 因此你需要手动将中文复制到其字体路径中去.
具体的路径位置和你当前使用python的site-packages路径有关, 在Linux中这个路径有可能在/usr/lib/python*下也有可能在~/.local/lib/python*下, 而在Windows中这个路径应该在你的python安装路径下.
那么具体的字体文件夹路径在哪里呢?假设$site-packages是你的site-packages路径, 那么字体目录在$site-packages/matplotlib/mpl-data/font下. 当然这个目录下一般会有afm pdfcorefonts ttf三个文件夹, 一般我们添加的都是ttf字体, 因此一般是添加到该目录下. 注意ttc字体放在这个目录下并不能被识别
比较推荐的代码字体有: 更纱黑体, 思源黑体.
更纱黑体是某个在微软工作的大佬正在开发而且不断在维护的一个字体, 效果很棒.
思源黑体是Adode开源的一个字体, 对于汉字和字幕都有着很好的效果.
总体来说, 这两个字体的显示效果差不多, 细节上略有差别, 具体的细节可以戳这里.

清空字体缓存

rm -rf ~/.cache/matplotlib

只有正确清空了字体缓存, 你的字体才会被Matplotlib再次识别. 对于Windows, 这个路径可能在C:\Users\$username\.matplotlib下.

查看已经添加在Matplotlib中的字体名

from matplotlib.font_manager import FontManager

fm = FontManager()
mat_fonts = set(f.name for f in fm.ttflist)
print(mat_fonts)

在Matplotlib中是使用字体名来配置字体的, 而不是字体的文件名, 因此你需要是从这里读到的字体名来进行下面的配置, 同时也可以查看之前的添加字体操作是否成功.

修改Matplotlib的字体配置

修改Matplotlib的字体配置, 有两种方法:
一种是我们可以在代码中修改配置;
另外一种是我们可以去修改Matplotlib的配置文件;

在代码中修改配置

通过plt.rcParams['$config_item']就可以修改Matplotlib的字体配置选项.
Matplotlib中一共有五种类型的字体, 分别是:

plt.rcParams['font.serif']=['Sarasa Mono SC'] # 衬线字体
plt.rcParams['font.sans-serif']=['Sarasa Mono SC'] # 无衬线字体
plt.rcParams['font.cursive']=['Sarasa Mono SC'] # 手写字体
plt.rcParams['font.fantasy']=['Sarasa Mono SC'] # 梦幻字体
plt.rcParams['font.monospace']=['Sarasa Mono SC'] # 等宽字体

直接修改配置文件

通过下面的代码可以读取到matplotlib的配置文件, 当然这个配置文件一般在$site-packages/matplotlib/mpl-data/matplotlibrc下:

import matplotlib

print(matplotlib.matplotlib_fname())

在这个文件搜索font.serif就会看到之前说的五大字体族了, 去掉前面的#号注释, 再在:前加上你的字体名就可以添加字体了的说.

最后的效果如图所示

QQ截图20180511151753.png


在WSL运行32位应用程序的神奇操作


在WSL运行32位应用程序的神奇操作

原理

主要的操作是通过qemu-i386-static模拟来运行x32程序, 然后通过binfmt来指定使用qemu来运行给定x32二进制文件

首先需要开启debian的x32基础支持

dpkg --add-architecture i386
apt-get update
apt-get install libstdc++6:i386

这会在dpkg中添加i386架构, 这样就可以通过apt工具安装i386的包了, 然后安装libstdc++会自动安装libc6/libgcc_s, 这样就可以运行基本的x32程序了.
一般的Linux到这一步就已经可以运行x32的程序了, 但是对于WSL来说还是不行, 使用ldd exec依然会告诉你这不是一个可执行文件, 于是说我们需要安装qemu.

安装qemu

apt-get update
apt-get install qemu-user-static

这样我们就可以通过qemu-i386-static exec来实际的运行我们想要的x32程序了, 但是这样很麻烦, 于是我们可以配置binfmt来自动使用qemu来运行qemu.

配置binfmt

update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'
service binfmt-support start

这样, 我们就可以像在正常Linux里面一样运行x32的程序了. 真是非常神奇的操作_(:3」∠)_

后记

当然每次启动要记得启动一下binfmt服务才行.

service binfmt-support start

Reference: https://github.com/Microsoft/WSL/issues/2468#issuecomment-374904520


博客又又又搬家了&VPS折腾记录


搬迁到新的VPS

现在的博客已经从之前的Banwagon搬迁到了UltraVPS上, 虽然年付用从$19变成了$40, 但是依然感觉很值:
一方面是线路很棒, LA的QN机房, IPV6线路到达LA之后只要四跳总跳数是14跳, IPV4线路也是差不多的, 但是因为我这边要先去北京赛尔的机房所以总跳数是17跳.
另外一方面是配置感人, 双核2G+(50G+10G)SSD, 这个配置只要$3.33每月真的感觉很难找到第二家了, 何况还是KVM, 线路质量也好, 也支持IPV6, 简直完美.

为什么会是(50G+10G)呢...
这是因为我第一次见到有商家虽然说是50G, 但是其实另外给了你10G用来装系统, 然后50G是完全的数据分区的...
于是我用了btrfs, 将这两个虚拟硬盘做成了一个逻辑卷嗯[Btrfs大法好

详细的评测+安利可以看这篇博文: https://blog.cysi.me/2018/03/new-vps-ultravps-providerservice.html
我当初就是看了这个之后心动的_(:3」∠)_
50G的SSD虽然不多, 但是对于自用的Seafile完全足够, 而且2G RAM对于Seafile Pro的配置条件也完全满足, 嗯
所以现在这上面部署了我的博客和Seafile还有你懂的服务.

购买的话, 这家似乎支持PayPal, 然后反欺诈还蛮严格的, 请务必填上看起来没问题的联系信息, 不然订单不会通过审核的.

具体的使用情况的话, 可能是开会已经开完了, 所以SSH上去不会突然就断掉, 也没有SSH很卡的情况, 虽然没法和本地路由器比, 但是也还是可以接受的.
说起来, 这家的KVM居然可以通过cat /proc/cpuinfo看到CPU类型, 是E5-2670.
看起来似乎母鸡是多CPU的, 不过很迷啊, 为什么CPU是这么老旧的一代E5...这个CPU不是都上岸多年了吗...
不过反正便宜就不管那么多了, 而且我真的没有任何需要CPU性能的服务.
IO的话...大概读写240M/s的样子, emmm凑合吧, 毕竟便宜.
ping值从170ms-240ms不等, HTTP下载速度的话, 大概最快可以接近4M/s...
不过主要还是看脸的, 线路路由会随时间而变化= =
比如说一开始是从武汉移动从上海出国的, 然后现在就变成了走教育网从北京出国...
总而言之, 这么便宜, 又能满足各项需求, 很适合自己的情况, 还要什么自行车啊.

最近试用了一下Syncthing...不得不说线路质量真是棒啊_(:3」∠)_
在IPV4环境下的上下行带宽:
QQ截图20180410133805.png
上下行感觉很明显是被限制在20Mbps的样子...
看了一下路由感觉是走了学校的电信出口, 所以可能是在学校的出口被限速了吧应该
在IPV6环境下的上下行带宽:
QQ截图20180410133204.png
这个上行带宽真的是吓哭我了, 第一次在公网见到这么高速率好吗!
说起来这个上行带宽的上升曲线, 真是生动形象的TCP慢启动过程啊233
下行的带宽虽然不及上行带宽, 但是还是非常可以的.
明明服务器上用了BBR, 上下行的路由还是一样的, 为什么带宽差这么多呢_(:3」∠)_
不是很懂(有可能是网络环境的影响吧, 比如说被大量PT流量给拥塞了什么的

博客搬迁

博客系统还是Typecho, 这货在死了几年以后居然STM的诈尸了. 不过更新之后, 多了一个很棒的功能就是备份还原.
这样博客的搬迁工作就非常简单了, 只要在原博客上备份, 再来新博客上还原就好, 也不用倒腾数据库了, 而且似乎我也没啥文件的样子...

然后过了这么几年, 我也从服务器小白逐渐进阶, 原来用的是LNMP的一键安装包, 现在还是觉得手动配置Nginx和PHP比较好.
然后网站前几天也弄了全站HTTPS, 用的是Let's encrypt的证书啦, 不过因为用了cloudflare的CDN, 所以拿到的证书可能是cf的共享证书...
然后用了大佬的自动部署脚本: https://github.com/gileshuang/letsautoencrypt
这个站点还有多个备份域名, 比如说:
http://www.slkun.me / http://blog.slkun.me
http://www.doris.work / http://blog.doris.work
http://www.lovedoris.moe / http://blog.lovedoris.moe
= =嗯 那个lovedoris.moe是没有cf的CDN部署的
然后哦Nginx的部署其实还是折腾了一下的= =因为其实对Nginx并不熟悉, 配置如下需要的可以参考:

server {
    listen       localhost:port;
    server_name  domainName;

    access_log  /nginx/logs/typecho.access.log;
    error_log  /nginx/logs/typecho.error.log;

    root        webRoot;
    index       index.php index.html index.htm;

    location / {
        if (!-e $request_filename) {
            rewrite ^(.*)$ /index.php$1 last;
        }
    }

    location ~ '\.php(/|$)' {
        include        fastcgi.conf;
        fastcgi_pass   unix:/run/php-fpm/php-fpm.sock;
        fastcgi_split_path_info       ^(.+\.php)(.*)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
    }

    # redirect server error pages to the static page /50x.html
    #error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

VPS折腾史

在16年入手了Bandwagon的256M VPS以后, 突然看到这家又推出了PHOENIX AZ的Special套餐, 年付$18就可以有1G RAM+20G SSD, 于是脑子一热就入手了.
因为位置问题, 所以ping值是会高一些, 然后路由一般般吧. 性能的话...emmm Xean D-1540? 我第一次听说这个系列的志强= = IO还是一如既往的优秀平均500+M/s

本来之前用这个256M的主要是因为这款的机房可切换, 万一要是ip翻车我还可以换个机房继续用, 可是用了一年多感觉非常稳, 完全没有任何问题.
但是以防万一, 所以这个256M的还是一直在用, 然后那个1G的因为硬盘大内存多, 于是我就在上面装了Seafile的服务, 用于文件同步和备份.
Seafile的话又是一个可以吹一波的好用软件, 这个的话以后再写好了.

后来, 正好之前那个256M的到期, 加上Banwagon推出了KVM的VPS, 然后还是联通和CN2直连的, 内存也是512M, 年付$28. 考虑到IPV6我可以用之前那个PHOENIX AZ, 而且PHOENIX AZ的那个在公网的使用体验不佳, 原来的256M一方面是OVZ而且内存太小, 于是就入手了这个.
其实也考虑过别的VPS商家, 比如说DigitalOcean, Vultr, Linode之类的, 但是最低$5/mo的价格实在是感人肺腑, 而且开了Vultr和DigitalOcean试用, 线路带宽实在堪忧, HTTP下载速度不超过100K/s, 这个就非常尴尬了. 所以就觉得Banwagon虽然便宜, 但是还慢靠谱的(对于我的网络环境来说)
这个CN2直连果然还是满靠谱的, 因为KVM所以并不清楚CPU的型号, 但是IO如上一样平均600+M/s吧. 线路的话, ping只有160ms左右吧, HTTP下载速度基本是不会低于500K/s的, 一般是1M/s左右, 好的话可以到2M/s.

随着照片什么的备份多了起来, 逐渐感觉20G SSD开始不够用了起来, 而且PHOENIX AZ的这个的速度突然变得非常慢, 又是HTTP下载速度不超过100K/s的节奏(确切的说是ipv6线路, ipv4线路好像还可以). 而且这个是OVZ的虚拟化, 没法换内核, 也就没法BBR, 很多L2TP之类的操作也没法弄, 于是就开始物色有没有存储更多价格差不多的VPS来替换.

正好看到小伙伴有推荐Virmach, 然后看了一下感觉这个价格真...
我本来以为$20年付已经非常便宜了...没想到还是$10年付的OVZ, 甚至还有$12.5年付的KVM...
我只感觉这家是不是分分钟要跑路啊, 再加上看到这个其实有点犹豫.
但是看到年付$35的512M RAM + 500G HDD瞬间就没了脾气, 决定先开一个月试试看, 结果没注意是备货状态= =
不过前几天也正式部署了, 虽然说是500G, 但其实只有465G, 感觉像是挂了一个500G的物理硬盘的感觉...不会是单盘吧= =
性能嘛...嗯 真TM感人...和当年我笔记本的那个超薄7mm硬盘差不多...IO读写不上百你敢信? 大概只有50-70M/s的样子...
网络情况...虽然是在NY, 虽然ping值很高, 但是HTTP下载还可以, 平均2M/s左右吧...所以还是有点可用性的
不过的话, 我已经有了50G SSD的那个了, 所以这个其实没啥需求了嗯

关于VPS的推荐和介绍, 可以看一下这篇博文, 写得挺全的: https://yorkchou.com/host-provider.html
然后后悔自己黑五的时候怎么没多关注一下_(:3」∠)_

所以现在手上有三个VPS, 到时候可能那两个Bandwagon就不续费了, 然后考虑弄一个日本来玩嗯(如果Vultr$2.5有货的话)


【转/备份】用遗忘曲线背单词的具体战略:本人四年利用遗忘曲线背单词实战的总结,传授轻松牢固背单词的秘诀~


原文位于:http://blog.renren.com/blog/225966891/480203439

用本人四年利用遗忘曲线背单词实战的总结,传授轻松牢固背单词的秘诀~ (本人英语德语都这么背的,方法不断调整过,四年过去了,此最终版本感觉最有效率,感觉不传授给别人太可惜了,就花了两小时认真总结了一下,尽量做到简明易学~~欢迎借鉴!)

准备工作:A3纸 (也可A4纸横过来用,一排写的下五个单词即可)。 这就开始背新的单词吧!

  1. 每个新词前都标上序号,从1开始。
  2. 背新单词的方式是:连读带写三遍,写成一排。
  3. 每背完第n个生词后,复习第n-2, n-6, n-24个单词,复习方式也是连读带写,只要写一遍,与原先三遍写在同一行。

具体地说,就是:

  • 背完第1个、第2个单词后都没单词可复习;

  • 背完第3个单词后,复习第1个单词,之后每背完一个新单词就在第n-2列下挪一个单词复习,效果如下:

    新背单词边读中英文边抄写三遍 复习n-2 复习n-6 复习n-24
    (1) abase   abase   abase   abase 
    (2) abashed abashed abashed 
    (3) abate   abate   abate
    

  • 背完第7个单词后,不仅复习第5个单词,还要复习第1个单词,之后每背完一个新单词就在第n-2列和第n-6列各下挪一个单词复习,效果如下:

    新背单词边读中英文边抄写三遍 复习n-2 复习n-6 复习n-24
    (1)abase    abase    abase    abase   abase 
    (2)abashed  abashed  abashed  abashed 
    (3)abate    abate    abate    abate 
    (4)abbess   abbess   abbess   abbess 
    (5)abdicate abdicate abdicate abdicate 
    (6)abdomen  abdomen  abdomen 
    (7)abduct   abduct   abduct
    

  • 背完第25个单词后,不仅复习第23个、第19个单词,还要复习第1个单词,之后每背完一个新单词就在第n-2列、第n-6列和第n-24列各下挪一个复习。效果如下:

     新背单词边读中英文边抄写三遍 复习n-2 复习n-6 复习n-24
     (1) abase      abase     abase     abase    abase   abase 
     (2) abashed    abashed   abashed   abashed  abashed 
     (3) abate      abate     abate     abate    abate 
     (4) abbess     abbess    abbess    abbess   abbess 
     (5) abdicate   abdicate  abdicate  abdicate abdicate
     (6) abdomen    abdomen   abdomen   abdomen  abdomen
     (7) abduct     abduct    abduct    abduct   abduct
     ……
     (19) accede    accede    accede    accede   accede 
     (20) acclaim   acclaim   acclaim   acclaim 
     (21) accordion accordion accordion accordion
     (22) acrid     acrid     acrid     acrid 
     (23) acquiesce acquiesce acquiesce acquiesce
     (24) accredit  accredit  accredit 
     (25) acoutics  acoutics  acoutics
    

  • 背到第48个单词大约正好一小时,将第48个单词读写三遍并复习完第46、42、24个单词后,你会发现最后几个单词的第二遍、甚至第一遍复习都还没做。所以,过一分半钟复习第47、48个单词,再过一分钟复习第43、44、45个单词,此后再过4分钟再次复习第46、47、48个单词。

  • 然后调好闹钟,30分钟后复习第25至48个单词,这是剩余单词的第三遍复习。

  • 此后再过8个小时,将全部48个单词复习一遍。

  • 然后就是隔天以后的复习了:第m天除了完成当天所记单词的复习外,还要复习第m-1天(与上一次复习的时间间隔尽量准确到24小时)、m-3、m-7、m-15、m-31、m-63天的单词(若减后为负数则不用复习,是正数的都要复习)。

用这样的方法,一天背100个单词轻轻松松而且不易遗忘,不过不要连续背两个小时新单词,最好早上一次下午一次。

为了说明方便,我们给每48个单词归为一组,各标组别号1、2、3、4……奇数组都在9 am.背,在7 pm.复习;偶数组都在12 am.背,在10 pm.复习。

比如说,9 am.背了第1组单词,其第4遍复习时间大约是7 pm.,第5遍复习时间安排在第二天的7 pm.,以后每次隔几天以后复习第1组可以都放在7 pm.这个时间。第2组单词放在12 am.背,于是他们的第4遍复习时间就放在10 pm.,第5遍复习时间也安排在第二天的10 pm.,以后每次复习第2组可以都放在10 pm.这个时间。这样分散开来背和复习就不会导致负荷太重坚持不下去。

最后算个帐吧,我06年买的英语专业八级单词词汇必背手册上约有5000个单词,按照一天背96个生词的速度,52天能背完。因此,负荷最重的几天是第32至52天,届时每天总共复习6天的单词,即复习576个(包括当天新背单词),每次复习238个(因为奇数组合偶数组时间错开)。这计划本人试过,基本没有疲劳感,故推荐给希望高效背单词的同仁们!

注意:复习非常关键,如果某天有事没时间,宁可不要背新的单词,务必将过去背过的在这一天需要复习的内容复习一遍!否则搞不好要就事倍功半啦~


Hibernate 5.1.1 + Spring 4.2.9 + Proxool 0.8.3 踩坑记录


起因

折腾的原因完全来自于我不想把DataSource配置到Spring的ApplicationContext中去.
希望Hibernate能够单独用一个配置文件, 这样就可以脱离Spring单独调试数据库部分的代码.

前提

原本在Spring 3.x + Hibernate 2.x的条件下已经成功了, 但是迁移到新版本就产生了各种各样的神奇的坑.

第一个坑

在新版本的Hibernate中, 在不使用org.apache.commons.dbcp.BasicDataSource的情况下, 似乎是不能用内置的默认连接池的.
大概看了下, Proxool似乎性能比较好, 用的比较多于是打算用这货.

抄了下网上常见的配置, 大概是这样的:

        <property name="hibernate.connection.provider_class">org.hibernate.proxool.internal.ProxoolConnectionProvider</property>
        <property name="hibernate.proxool.pool_alias">DBPool</property>
        <property name="hibernate.proxool.properties">test.properties</property>

可是...并不能找到配置文件, 从Trace一层一层网上看, 似乎是不知道传进去的路径是什么类型...
想了想, 加了file://可是依然不行= =
翻了好久源码, 突然看到...这货好像是从classpath开始搜索的...
放在classpath下果然就行了= =

第二个坑

Caused by: org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource]

因为我把数据源配置在proxool里面, 所以明面上并没有给HibernateTransactionManager显式地传数据源...
可是HibernateTransactionManager在初始化的时候发现没有数据源会非常执着的去拿数据源, 拿不到还会去找ContentProvider要...可是并不能unwrap到数据源于是就报错了...
解决也很简单, HibernateTransactionManager有一个叫做autodetectDataSource的属性, 将其改为false即可.

第三个坑

其实算是我自己作死...
因为为了省事我把MVC和Spring的ApplicationContext写在一起了...
然后proxool会报错说配置文件已经配置...[md不能智能一点么]
想了想之前看的Spring文档, 好像Spring的Application和MVC并不是同一个Context.
又看了下web.xml...好像在ServletContext和Servlet的init-param里面指定了两遍...
于是把sessionFactory单独拿出来放在Application的Context配置里就可以了= =

第四个坑

这个也是很迷...看之前的书, 他告诉我Hibernate的current_session_context_class属性应当设置为thread.
我也就照着做了...可是我在执行任何操作的时候都会和我说Transcation没有ACTIVE???
追踪到TransacationManager里去也发现这里面的Transcation也正常的ACTIVE了.
可是执行的时候却拿不到ACTIVE过的session???
认真看了源码...好像它每次执行数据库操作的时候都是从Factory生成一个Session然后就去执行了...EXECUSE ME???
TransacationManger管理的Session呢???
查了好久发现...这篇文章难怪= =拿不到TransacationManger管理的Session啊_(:_」)_

配置了<property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>马上就好了(╯‵□′)╯︵┻━┻