BNU-FZH

fengzhenhua@outlook.com

问题描述

ubuntu是大多数人步入Linux世界的入门级系统,其易用性使得多数对系统配置不高的人容易接受这一系统。在我使用Linux的早期,也是使用了一段时间的ubuntu, 但是直到有一天,它经常出现,不得不让早期的我认为它不友好,于是转入Debian.它的错误对话框如下:

Ubuntu提示出现了内部错误

原因分析

Ubuntu桌面版预装了Apport,它是一个错误收集系统,会收集软件崩溃、未处理异常和其他,包括程序bug,并为调试目的生成崩溃报告。当一个应用程序崩溃或者出现Bug时候,Apport就会通过弹窗警告用户并且询问用户是否提交崩溃报告:

1
2
3
4
5
6
“Sorry, the application XXXX has closed unexpectedly.”   
“对不起,应用程序XXXX意外关闭了。” 
“Sorry, Ubuntu XX.XX has experienced an internal error.” 
“对不起,Ubuntu XX.XX 发生了一个内部错误。” 
“System program problem detected.” 
“检测到系统程序问题。”

实际情况并不是Ubuntu容易出现内部错误,而是一旦程序崩溃过一次,就会生成一个.crash文件,记录着崩溃信息,这些崩溃信息保存在目录: /var/crash/

只要你不去处理,每次开机都会提示你有错误。也就是说:报错并不一定是出现了什么错误,而是曾经出现过错误,而你没有处理。通常情况下,到/var/crash/目录查看崩溃文件,如果不是什么大问题(通常都没什么大问题),删除该目录下的崩溃文件,之后就不会再报错误了.。

解决方案

永久关闭Apport错误报告

修改Apport配置文件/etc/default/apport

/etc/default/apport
1
enabled=0

重启你的Ubuntu系统,Apport将会自动关闭 

完全移除Apport

1
sudo apt-get purge apport

编写Shell脚本的过程中,使用常用的图标符号增加美观的同时也增强了易用性, 比如使用软盘符💾、个人电脑符💻 等。 本文总结在Shell脚本中显示Unicode符号的方法:

查询 Unicode 编码

使用 echo 命令

例如查询到💾的Unicode编码为U+1F4BE, 则使用echo应当开启-e选项,即:

1
echo -e "\u0001F4BE"

使用 printf 命令

同样输出💾,使用printf命令为:

1
printf "\u0001F4BE"

使用 Python 脚本

1
print(u"\U0001F4BE")

使用 Perl 脚本

1
print "\x{1F4BE}\n" ;

在 Html 中使用 Unicode

Html中使用Unicode应当使用其专用的格式,例如https://www.unicodery.com/会直接给出。输出💾的源码为💾.

AttributeError: partially initialized module 'pandas' has no attribute 'DataFrame' (most likely due to a circular import)

PandasPython 语言的一个扩展程序库,用于数据分析。但是今天在使用pandas导出数据时,发现它报错了:

1
AttributeError: partially initialized module 'pandas' has no attribute 'DataFrame' (most likely due to a circular import)

经过研究发现它是由于我把同目录下的另一个测试程序改名为pandas.py导致的,然后修改了那个程序后,问题解决。

参考文章

控件简介

Veusz绘图,其将图像的各个部分称为widget(控件),对于每一个控件又分为Properties(属性)和Formatting(格式)在左侧边栏显示。如下图所示:

Widget、Properties and Formatting

在上图中,可以看到有pagegraph1axis(x 和 y 轴各一个)、colorbarimage一共六个组件. 它就像PhotoShop一样,将不同的组件放置于不同的, 当它们之前相互无遮挡时就可以从图上同时看到了。如果某一控件被遮蔽,则按住左边对应的控件,上下移动可以调整其层次,也可以通过右键来设置。

Colorbar 控件设置

  • 点击工具栏中的Colorbar按扭添加Colorbar控件:
添加Colorbar控件
  • 点击左侧Colorbar控件→Properties对话框,在Widget右侧的小箭头选择image1, 如果有多个图片则可以选择某一个image然后此Colorbar就对应显示该图片的Colorbar.
  • Properties中选择Direction可以设置Colorbar方向为水平horizontal还是垂直vertical方向,其中Axis设置数值标尺相对于Colorbar的位置。其中0对应于Colorbar的左侧,1对应于Colorbar的右侧,0.5就位于中央。
  • Formatting对话框中,选中Reflect则数值标尺变成在坚线的左侧,不选中默认在坚线的右侧。
  • Formatting对话框中,可以设置Horz posn (水平位置)和 Vert posn(垂直位置), 由于一般默认情况leftcenter,right会覆盖于图片上,所以选择manual手工设置,然后在对话框最下面找到Horz manual设置为1.05就会在图片的右侧呈现Colorbar.
  • 按上述设置,配置好Colorbar后,最终得到下图
Mandelbrot集

今天实现了使用Python绘图并保存为csv数据格式,然后将csv导入到veusz绘图。导出数据并单独绘图的意义在于,比如说使用蒙特卡洛方法处理数据然后得到一些二维图形,由于它包括了随机数据,同时还需要保证所得图像可以再编辑。这遇到了两个问题,如果每次都使用程序重新生成图像,由于随机数据所以不能保证每次数据都严格一致。同时,不同的期刊对图片格式有不同的要求,所以就需要图片可以再编辑,这种编辑不是Photo式的编辑,它需要确保清晰度,根据要求生成完全相同的图片,所以必须有数据保存下来,每次都使用绘图软件来处理数据才能得到一致的结果。

Python 生成Mandelbrot 集并保存为 csv文件

mandelbrot to csv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#! /usr/bin/env python3
# vim:fenc=utf-8
#
import numpy as np
import matplotlib.pyplot as plot
from pylab import *
import pandas as pd

x0=0 #初始值z0的x0
y0=0 #初始值z0的y0
zoom=1.0 #放大倍率
N=100 #最大迭代次数
R=2 #迭代半径
a=4.0 #绘制图的横轴大小
b=3.0 #绘制图的纵轴大小
step=0.005 #绘制点的步长

def iterate(c,N,R):
z=c
for i in range(N):
if abs(z)>R:
return i
z = z*z+c
return N

x=np.arange(-a/(2.0*zoom)+x0,a/(2.0*zoom)+x0,step)
y=np.arange(b/(2.0*zoom)+y0,-b/(2.0*zoom)+y0,-step)
cx,cy=np.meshgrid(x, y)
c = cx + cy*1j
ufunc=np.frompyfunc(iterate,3,1)
z=ufunc(c,N,R).astype(np.float64)

z = pd.DataFrame(z)
z.to_csv('test.csv')

Veusz 导入 csv 数据并绘图

  • 启动veuszDataImport...Browse...找到刚刚生成的test.csv,→2D 来到对话框:
2D数据导入对话框
  • 点击右下角import,成功导入数据。在软件右侧可以看到
2D数据成功导入
  • 软件左侧,点击graph1,在工具栏中点击image图标,如图
点击image图标
  • FileExport...,弹出导出对话框,保存为png图像:
Mandelbrot集

参考资料

近期在研究使用Python绘图,但是veusz官方网站上给出的例子好多都是Python2格式. 如果代码量比较少,则按照Python2.x与Python3.x版本区别一点一点的修改即可, 但是如果代码量比较大,那这一点一点的修改显然效率太低了。好在,Python3内置了一个转换工具2to3, 可以方便的完成从Python2.xPython3.x的转换工作。

2to3 简介

2to3 是一个 Python 程序,它可以用来读取 Python 2.x 版本的代码,并使用一系列的 修复器 来将其转换为合法的 Python 3.x 代码。标准库中已经包含了丰富的修复器,这足以处理绝大多数代码。不过 2to3 的支持库 lib2to3 是一个很灵活通用的库,所以你也可以为 2to3 编写你自己的修复器。lib2to3 也可以用在那些需要自动处理 Python 代码的应用中。

使用方法

2to3 的基本调用参数是一个需要转换的文件或目录列表。对于目录,会递归地寻找其中的 Python 源码。例如,一个Python2.x的源文件为:

python2.x:example.py
1
2
3
4
5
def greet(name):
print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)

它可以在命令行中使用 2to3 转换成 Python 3.x 版本的代码:

1
2to3 example.py

这个命令会打印出和源文件的区别。通过传入 -w 参数,2to3 也可以把需要的修改写回到原文件中(除非传入了 -n 参数,否则会为原始文件创建一个副本):

1
2to3 -w example.py

转换完成后,example.py 看起来像是这样:

python3.x:example.py
1
2
3
4
5
def greet(name):
print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)

注释和缩进都会在转换过程中保持不变。默认情况下,2to3 会执行 预定义修复器 的集合。使用 -l 参数可以列出所有可用的修复器。使用 -f 参数可以明确指定需要使用的修复器集合。而使用 -x 参数则可以明确指定不使用的修复器。下面的例子会只使用 imports 和 has_key 修复器运行:

1
2to3 -f imports -f has_key example.py

这个命令会执行除了 apply 之外的所有修复器:

1
2to3 -x apply example.py

有一些修复器是需要 显式指定 的,它们默认不会执行,必须在命令行中列出才会执行。比如下面的例子,除了默认的修复器以外,还会执行 idioms 修复器:

1
2to3 -f all -f idioms example.py

注意这里使用 all 来启用所有默认的修复器。

--add-suffix 选项接受一个字符串,用来作为后缀附加在输出文件名后面的后面。由于写入的文件名与原始文件不同,所以没有必要创建副本,因此 -n 选项也是必要的。举个例子:

1
2to3 -n -W --add-suffix=3 example.py

这样会把转换后的文件写入 example.py3 文件。将整个项目从一个目录转换到另一个目录可以用这样的命令:

1
2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode

参考文章

Python 推导式是一种强大且简洁的语法,适用于生成列表、字典、集合和生成器。在使用推导式时,需要注意可读性,尽量保持表达式简洁,以免影响代码的可读性和可维护性。

语法格式

语法格式
1
结果值1 if 判断条件 else 结果2  for 变量名 in 原列表

举例说明

代码

1
2
3
list1 = ['python', 'test1', 'test2']
list2 = [word.title() if word.startswith('p') else word.upper() for word in list1]
print(list2)

结果

1
['Python', 'TEST1', 'TEST2']

参考文章

Python2到Python3的问题修复

本文测试veusz绘制2D图形的能力,于是在官方网站下载了mandelbrot的经典例子:mandelbrot.vsz, 但是官方的例子是以python2构建的,而本文希望切换到python3解决问题。由于语法的兼容,需要做出少许修改:

  • 指明python2可以直接运行程序,但不是目前我想要的。
  • print函数,在python2中不需要加括号,但是python3中需要加括号,即print "hello world"print ("hello world")
  • python2中使用xrange函数,在python3中已经取消,合并到range函数。所以需要修改:xrange()range()
  • 错误:TypeError: ‘float‘ object cannot be interpreted as an integer. 造成错误的原因是range里面使用了小数,所以解决方法有两个:
    • python2中的/只保留整数部分,是int型。在python3中的/的结果是真正意义上的除法,得到的是一个小数,所以是float型,所以改用python3中的//得到一个整数,则问题解决。即:///
    • 如果不想任何改变仍要使用range的功能,则可以使用numpy中提供的arange,即
      1
      2
      for i in numpy.arange(0.0, 4.1, 0.8)
      print(i)

Python3下的mandelbrot.vsz

mandelbrot.vsz for pyton3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# Veusz script (version 0.7 or later)
# Jeremy Sanders (2005)
# for python3
# computes the Mandelbrot set in real time

size = 300
maxiters = 20
image = zeros( (size, size) )

print ("This takes some time, please wait")

minx = 100000
maxx = -100000
miny = 100000
maxy = -100000

for i in range(size):
for j in range(size//2):
c1 = -2+4.*i/size
c2 = 2-4.*j/size
x = c1
y = c2

minx=min(x, minx)
maxx=max(x, maxx)
miny=min(y, miny)
maxy=max(y, maxy)

n = 0
while n < maxiters and x**2+y**2 < 4.:
x1 = x**2-y**2+c1
y1 = 2*x*y+c2
x = x1
y = y1

n += 1

image[j, i] = n
image[size-j-1, i] = n

# set output data into veusz
SetData2D('image', image, xrange=(minx, maxx), yrange=(miny, maxy))

# construct the graph
To(Add('page'))
To(Add('graph'))

# Add a label
Add('label', label='The Mandelbrot Set', yPos=0.95,
alignHorz='centre', alignVert='top',
Text__size='30pt')

# add colorbar in front of image
Add('colorbar', name='colorbar1', image='image1',
direction='vertical', vertPosn='top')

# add image
Add('image', name='image1', data='image', min=1,
colorScaling='log', colorMap='heat', colorInvert=True)

# adjust axes
Set('x/min', -2.2)
Set('x/max', 1.2)
Set('y/min', 0.3)
Set('y/max', 1.9)

To('/')

运行结果

mandelbrot 集(python3 实现)

参考文章

Matplotlib 指定图形大小(单位厘米)

Matplotlib是Python中最常用的绘图工具之一。它可以用来画各种类型的图表,从简单的折线图到复杂的3D图。在Matplotlib中,可以指定图像的大小和分辨率。

本文将介绍如何在Matplotlib中指定图形大小,以及如何使用厘米单位。

确定图形大小

在Matplotlib中,可以使用plt.figure()函数来创建一个新的图像。该函数包括几个参数,其中一个是figsize,它可以用来指定图像的大小。

默认情况下,Matplotlib中的figsize参数是以英寸为单位的。但是,我们可以通过将figsize参数设置为一个包含两个数字的元组来指定图像的大小。第一个数字是图像的宽度,第二个数字是图像的高度。

例如,下面的代码将创建一个大小为4英寸x4英寸的图像:

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

# 创建一个大小为4英寸x4英寸的图像
fig = plt.figure(figsize=(4, 4))
ax = fig.add_subplot(111)

# 在图像中绘制一个正弦波
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
ax.plot(x, y)

plt.show()

你可以看到,这个图像略微有些小,无法清晰地显示。如果我们需要一个更大的图像,我们可以通过增加figsize参数中的数字来实现。例如,如果我们需要一个8英寸x8英寸的图像,我们可以将figsize参数设置为(8,8)

但是,如果我们想要以厘米为单位指定图像的大小,该怎么办呢?

使用厘米单位

默认情况下,Matplotlib使用英寸作为图像大小的单位。但是,我们可以使用其他单位来指定图像的大小,包括厘米。

要在Matplotlib中指定图像大小为厘米,我们需要使用Figure.set_size_inches()函数。该函数包括两个参数,分别是图像的宽度和高度,以英寸为单位。我们可以将这些参数转换为厘米,然后将它们传递给set_size_inches()函数。

例如,下面的代码将创建一个大小为8厘米x8厘米的图像:

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

# 创建一个大小为8英寸x8英寸的图像
fig = plt.figure(figsize=(8/2.54, 8/2.54))
ax = fig.add_subplot(111)

# 在图像中绘制一个正弦波
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
ax.plot(x, y)

plt.show()

你可以看到,这个图像与上面的图像相同,只是现在它的大小是以厘米为单位的。我们将figsize参数设置为(8/2.54, 8/2.54),其中8/2.54是以厘米为单位的8英寸。

注意,如果你使用的是Python2,你需要在8/2.54前面加上一个小数点,即.8/2.54

总结

在Matplotlib中,我们可以使用plt.figure()函数来创建一个新的图像,并使用figsize参数指定它的大小。默认情况下,figsize的大小是以英寸为单位的。我们可以通过将figsize设置为一个包含两个值的元组来调整它的大小。要使用厘米作为单位指定图像大小,我们需要使用Figure.set_size_inches()函数,并将宽度和高度转换为厘米。

文章参考

由于不想受限于MatLab,于是全面转入到Python工作,同时绘图工具使用免费开源的veusz, 在实现python导出数据,再使用veusz绘图时,第一步就是使用python正确的绘图,而分形图就是练习画这类图的绝佳素材。

Koch曲线

代码

Koch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import turtle

Division = 3.0
DirectionAangle = [('left',60),('right',120),('left',60)]

def call(name):
if name == 'left':
return turtle.left
else:
return turtle.right

def koch(n, length):
if n==0:
turtle.forward(length)
else:
for DA in DirectionAangle:
koch(n-1,length/Division)
call(DA[0])(DA[1])
koch(n-1,length/Division)

koch(n=4, length=400)
turtle.done()

运行结果

koch

Julia 集

代码

Julia
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import matplotlib.pyplot as plot
import numpy as np
p=0.45 #初始值c的实部
q=-0.1428 #初始值c的虚部
N=800 #最大迭代次数
M=100 #迭代区域的界值
a=3.0 #绘制图的横轴大小
b=3.0 #绘制图的纵轴大小
step=0.005 #绘制点的步长

def iterate(z,N,M):
z=z*z+c
for i in range(N):
if abs(z)>M:
return i
z=z*z+c
return N

c=p+q*1j
i=np.arange(-a/2.0,a/2.0,step)
j=np.arange(b/2.0,-b/2.0,-step)
I,J=np.meshgrid(i, j)
ufunc=np.frompyfunc(iterate,3,1)
Z=ufunc(I+1j*J,N,M).astype(np.float64)
plot.imshow(Z,extent=(-a/2.0,a/2.0,-b/2,b/2.0))
cb = plot.colorbar(orientation='vertical',shrink=1)
cb.set_label('iteration counts')
plot.show()

运行结果

Julia集

Mandelbrot 集

代码

Mandelbrot
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
import matplotlib.pyplot as plot

x0=0 #初始值z0的x0
y0=0 #初始值z0的y0
zoom=1.0 #放大倍率
N=100 #最大迭代次数
R=2 #迭代半径
a=4.0 #绘制图的横轴大小
b=3.0 #绘制图的纵轴大小
step=0.005 #绘制点的步长

def iterate(c,N,R):
z=c
for i in range(N):
if abs(z)>R:
return i
z = z*z+c
return N

x=np.arange(-a/(2.0*zoom)+x0,a/(2.0*zoom)+x0,step)
y=np.arange(b/(2.0*zoom)+y0,-b/(2.0*zoom)+y0,-step)
cx,cy=np.meshgrid(x, y)
c = cx + cy*1j
ufunc=np.frompyfunc(iterate,3,1)
Z=ufunc(c,N,R).astype(np.float64)
plot.imshow(Z,extent=(-a/2.0,a/2.0,-b/2,b/2.0))
cb = plot.colorbar(orientation='vertical',shrink=1)
cb.set_label('iteration counts')
plot.show()

运行结果

Mandelbrot 集

说明

本文参考文章: 使用 Python 绘制分形: Koch 曲线、Julia 集、Mandelbrot 集, 文章发布于2017年1月25日, 比较早。其使用的是python2, 而当前使用更加先进的python3更加合理,于是切换为python3代码后,出现几处错误,本文逐一更正。

python3 xrange 报错

由于python3取消了在python2中定义的xrange函数,取而代之的是range, 于是在修改后的代码中改xrangerange.

AttributeError: module 'numpy' has no attribute 'float'.

直接运行程序时,会提示:

1
2
3
4
AttributeError: module 'numpy' has no attribute 'float'.
`np.float` was a deprecated alias for the builtin `float`. To avoid this error in existing code, use `float` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.float64` here.
The aliases was originally deprecated in NumPy 1.20; for more details and guidance see the original release note at:
https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations. Did you mean: 'float16'?

于是根据提示:将np.float修改为np.float64解决问题。

ImportError: libtk8.6.so: cannot open shared object file: No such file or directory

造成这个问题的原因是系统没有安装程序tk,安装即可解决问题:

1
sudo pacman -S tk

Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .TkTkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 WindowsMacintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格, 并良好地运行在绝大多数平台中。详情参考:Python GUI编程(Tkinter)