跳到主要内容
Python 数据可视化实战:环境搭建与数据读取入门 | 极客日志
Python 算法
Python 数据可视化实战:环境搭建与数据读取入门 本文介绍 Python 数据可视化的基础实践,涵盖 Matplotlib 环境安装配置、多种数据源(CSV、Excel、JSON、数据库)的读取方法,以及异常值清理和基础图表绘制技巧。通过实际代码示例,演示如何从原始数据到生成可视化结果的完整流程,帮助开发者快速掌握数据清洗与绘图的核心技能。内容包含环境准备、数据导入、数据清洗及各类图表(折线图、柱状图、散点图等)的自定义设置。
Python 数据可视化实战指南
最好的数据是我们能看到和理解的数据。作为开发人员,我们希望创建和构建最全面、最容易理解的可视化。这并不总是简单的;我们需要找到数据,阅读它,清洗它,然后使用正确的工具来可视化它。
本文旨在解释如何用简单明了的方法来阅读、清理数据并将其可视化为信息的过程。我们将涵盖如何读取本地数据、远程数据、CSV、JSON 以及关系数据库中的数据,并使用 Matplotlib 绘制图表。
一、准备工作环境
在本节中,我们将介绍安装所需 Python 包和库的方法和建议。
1. 安装 Matplotlib、NumPy 和 SciPy
本章描述了在 Linux 下安装 Matplotlib 和所需依赖项的几种方式。
准备工作
我们假设你已经安装了 Linux(最好是 Debian/Ubuntu)并且上面安装了 Python。通常,Python 已经安装在提到的 Linux 发行版上。我们建议您的工作站上安装 Python 3.x 版本,虽然部分旧代码可能基于 Python 2.7,但现代开发推荐使用 Python 3。
Matplotlib 需要 NumPy 、libpng 和 freetype 作为构建依赖项。
$ sudo apt-get install build-dep python-matplotlib
$ su -c 'yum-builddep python-matplotlib'
检查安装版本:
$ python -c 'import numpy; print(numpy.__version__)'
安装 Python-NumPy 包:
$ sudo apt-get install python-numpy
可以通过多种方式安装 Matplotlib 及其依赖项:从源代码、预编译的二进制文件、从 OS 包管理器,以及使用预打包的 Python 发行版。
最简单的方法是使用发行版包管理器。对于 Ubuntu:
$ sudo apt-get install python-numpy python-matplotlib python-scipy
如果你想尝试从源码安装,可以下载最新源代码:
$ cd ~/Downloads/
$ wget https://github.com/matplotlib/matplotlib/archive/v1.5.0.tar.gz
$ tar xzf matplotlib-1.5.0.tar.gz
$ cd matplotlib-1.5.0
$ python setup.py build
$ sudo python setup.py install
2. 安装 Virtualenv 和 Virtualenvwrapper
如果你同时在多个项目上工作,或者频繁地在它们之间切换,你会发现 virtualenv 很有用。它使开发者能够隔离每个项目的工作环境。
安装 virtualenv 和 virtualenvwrapper 工具:
$ sudo pip install virtualenv
$ sudo pip install virtualenvwrapper
$ VIRTENV=~/.virtualenvs
$ -p
$ /usr/local/bin/virtualenvwrapper.sh
$ mkvirtualenv myproject
export
mkdir
$VIRTENV
source
mkworkon ENV: 激活之前创建的 ENV
deactivate: 脱离当前的虚拟环境
3. 其他平台安装 Mac OS X: 建议使用 Homebrew 安装 Python 和依赖项。
$ brew install python
$ pip install numpy scipy matplotlib
Windows: 建议安装预打包的 Python 科学发行版,如 Anaconda 或 Enthought Python Distribution (EPD)。
4. 安装图像处理库 (PIL/Pillow) Python 图像库 (PIL) 用于图像处理。现在推荐使用其分支 Pillow。
5. 安装 Requests 模块 大多数数据可以通过 HTTP 获取,Requests 库使这项工作变得简单。
import requests
r = requests.get('https://api.github.com/timeline' )
print (r.content)
6. 自定义 Matplotlib 参数 Matplotlib 配置可以从配置文件 .rc 文件中读取,也可以在代码中修改。
import matplotlib as mpl
mpl.rcParams['lines.linewidth' ] = 2
mpl.rcParams['lines.color' ] = 'r'
import matplotlib as mpl
mpl.rc('lines' , linewidth=2 , color='r' )
若要恢复默认设置,可调用 matplotlib.rcdefaults()。
二、了解你的数据 本节介绍从各种格式导入和导出数据的基本知识,以及清理数据的方法。
1. 从 CSV 导入数据 Python 有 csv 模块支持读写 CSV 文件。
import csv
filename = 'ch02-data.csv'
data = []
try :
with open (filename) as f:
reader = csv.reader(f)
header = next (reader)
data = [row for row in reader]
except csv.Error as e:
print ("Error reading CSV file at line %s: %s" % (reader.line_num, e))
import sys
sys.exit(-1 )
if header:
print (header)
for datarow in data:
print (dat ar ow)
对于大文件,可以使用 NumPy 的 loadtxt():
import numpy
print (numpy.loadtxt('ch02-data.csv' , dtype='string' , delimiter=',' ))
2. 从 Excel 文件导入数据 import xlrd
file = 'ch02-xlsxdata.xlsx'
wb = xlrd.open_workbook(filename=file)
ws = wb.sheet_by_name('Sheet1' )
dataset = []
for r in range (ws.nrows):
col = []
for c in range (ws.ncols):
col.append(ws.cell(r, c).value)
dataset.append(col)
from pprint import pprint
pprint(dataset)
3. 从固定宽度数据文件导入 import struct
import string
datafile = 'ch02-fixed-width.data'
mask = '9s14s5s'
with open (datafile, 'r' ) as f:
for line in f:
fields = struct.Struct(mask).unpack_from(line)
print ('fields:' , [field.strip() for field in fields])
4. 从 JSON 资源导入数据 import requests
url = 'https://github.com/timeline.json'
r = requests.get(url)
json_obj = r.json()
repos = set ()
for entry in json_obj:
try :
repos.add(entry['repository' ]['url' ])
except KeyError as e:
print ("No key %s. Skipping..." % e)
5. 将数据导出到 JSON、CSV、Excel import csv
import json
import xlwt
def write_csv (data ):
import io
f = io.StringIO()
writer = csv.writer(f)
for row in data:
writer.writerow(row)
return f.getvalue()
def write_json (data ):
return json.dumps(data)
def write_xlsx (data ):
book = xlwt.Workbook()
sheet1 = book.add_sheet("Sheet 1" )
row = 0
for line in data:
col = 0
for datum in line:
sheet1.write(row, col, datum)
col += 1
row += 1
f = io.StringIO()
book.save(f)
return f.getvalue()
6. 从数据库导入数据 使用 sqlite3 连接 SQLite 数据库。
import sqlite3
con = sqlite3.connect('world.db' )
with con:
cur = con.cursor()
query = 'SELECT ID, Name, Population FROM City ORDER BY Population DESC LIMIT 1000'
cur.execute(query)
resultset = cur.fetchall()
col_names = [cn[0 ] for cn in cur.description]
print ('%10s %30s %10s' % tuple (col_names))
for row in resultset:
print ('%10s %30s %10s' % row)
7. 从异常值中清除数据 import numpy as np
import matplotlib.pyplot as plt
def is_outlier (points, threshold=3.5 ):
if len (points.shape) == 1 :
points = points[:, None ]
median = np.median(points, axis=0 )
diff = np.sum ((points - median)**2 , axis=-1 )
diff = np.sqrt(diff)
med_abs_deviation = np.median(diff)
modified_z_score = 0.6745 * diff / med_abs_deviation
return modified_z_score > threshold
x = np.random.random(100 )
x = np.r_[x, -49 , 95 , 100 , -100 ]
filtered = x[~is_outlier(x)]
plt.figure()
plt.subplot(211 )
plt.hist(x, buckets=50 )
plt.xlabel('Raw' )
plt.subplot(212 )
plt.hist(filtered, buckets=50 )
plt.xlabel('Cleaned' )
plt.show()
8. 分块读取文件 import sys
filename = sys.argv[1 ]
with open (filename, 'rb' ) as hugefile:
chunksize = 1000
readable = ''
while True :
start = hugefile.tell()
file_block = ''
for _ in range (chunksize):
line = hugefile.next ()
file_block = file_block + line
readable = readable + file_block
stop = hugefile.tell()
print ('reading bytes from %s to %s' % (start, stop))
9. 读取流数据源 import time
import os
import sys
if len (sys.argv) != 2 :
print ("Please specify filename to read" )
sys.exit(1 )
filename = sys.argv[1 ]
if not os.path.isfile(filename):
print ("Given file is not a file" )
sys.exit(1 )
with open (filename, 'r' ) as f:
filesize = os.stat(filename)[6 ]
f.seek(filesize)
while True :
where = f.tell()
line = f.readline()
if not line:
time.sleep(1 )
f.seek(where)
else :
print (line, end='' )
10. 将图像数据导入 NumPy 数组 import scipy.misc
import matplotlib.pyplot as plt
lena = scipy.misc.lena()
plt.gray()
plt.imshow(lena)
plt.colorbar()
plt.show()
print (lena.shape)
print (lena.max ())
print (lena.dtype)
11. 生成受控随机数据集 import random
import pylab
SAMPLE_SIZE = 100
random.seed()
real_rand_vars = [random.random() for val in range (SAMPLE_SIZE)]
pylab.hist(real_rand_vars, 10 )
pylab.xlabel("Number range" )
pylab.ylabel("Count" )
pylab.show()
12. 平滑真实数据中的噪声 from pylab import *
from numpy import *
def moving_average (interval, window_size ):
window = ones(int (window_size))/float (window_size)
return convolve(interval, window, 'same' )
t = linspace(-4 , 4 , 100 )
y = sin(t) + randn(len (t))*0.1
plot(t, y, "k." )
y_av = moving_average(y, 10 )
plot(t, y_av, "r" )
xlabel("Time" )
ylabel("Value" )
grid(True )
show()
三、绘制你的第一个图并自定义它们 Matplotlib 是一个强大的工具箱,几乎满足了我们对 2D 绘图的所有需求。
1. 定义绘图类型 from matplotlib.pyplot import *
x = [1 , 2 , 3 , 4 ]
y = [5 , 4 , 3 , 2 ]
figure()
subplot(231 )
plot(x, y)
subplot(232 )
bar(x, y)
subplot(233 )
barh(x, y)
subplot(234 )
bar(x, y)
y1 = [7 , 8 , 5 , 3 ]
bar(x, y1, bottom=y, color='r' )
subplot(235 )
boxplot(x)
subplot(236 )
scatter(x, y)
show()
2. 绘制正弦和余弦图 import matplotlib.pyplot as pl
import numpy as np
x = np.linspace(-np.pi, np.pi, 256 , endpoint=True )
y = np.cos(x)
y1 = np.sin(x)
pl.plot(x, y)
pl.plot(x, y1)
pl.title("Functions $\sin$ and $\cos$" )
pl.xlim(-3.0 , 3.0 )
pl.ylim(-1.0 , 1.0 )
pl.xticks([-np.pi, -np.pi/2 , 0 , np.pi/2 , np.pi],
[r'$-\pi$' , r'$-\pi/2$' , r'$0$' , r'$+\pi/2$' , r'$+\pi$' ])
pl.yticks([-1 , 0 , +1 ], [r'$-1$' , r'$0$' , r'$+1$' ])
pl.show()
3. 定义轴长度和极限 l = [-1 , 1 , -10 , 10 ]
axis(l)
4. 设置刻度、标签和网格 from pylab import *
ax = gca()
ax.locator_params(tight=True , nbins=10 )
ax.plot(np.random.normal(10 , .1 , 100 ))
show()
5. 添加图例和标注 from matplotlib.pyplot import *
x1 = np.random.normal(30 , 3 , 100 )
x2 = np.random.normal(20 , 2 , 100 )
plot(x1, label='plot' )
plot(x2, label='2nd plot' )
legend(bbox_to_anchor=(0. , 1.02 , 1. , .102 ), loc=3 , ncol=3 , mode="expand" , borderaxespad=0. )
annotate("Important value" , (55 , 20 ), xycoords='data' , xytext=(5 , 38 ),
arrowprops=dict (arrowstyle='->' ))
show()
6. 将脊椎移向中央 import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-np.pi, np.pi, 500 , endpoint=True )
y = np.sin(x)
plt.plot(x, y)
ax = plt.gca()
ax.spines['right' ].set_color('none' )
ax.spines['top' ].set_color('none' )
ax.spines['bottom' ].set_position(('data' , 0 ))
ax.spines['left' ].set_position(('data' , 0 ))
ax.xaxis.set_ticks_position('bottom' )
ax.yaxis.set_ticks_position('left' )
plt.show()
7. 制作直方图 import numpy as np
import matplotlib.pyplot as plt
mu = 100
sigma = 15
x = np.random.normal(mu, sigma, 10000 )
ax = plt.gca()
ax.hist(x, bins=35 , color='r' )
ax.set_xlabel('Values' )
ax.set_ylabel('Frequency' )
ax.set_title(r'$\mathrm{Histogram:}\ \mu=%d,\ \sigma=%d$' % (mu, sigma))
plt.show()
8. 用误差线制作条形图 import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0 , 10 , 1 )
y = np.log(x)
xe = 0.1 * np.abs (np.random.randn(len (y)))
plt.bar(x, y, yerr=xe, width=0.4 , align='center' , ecolor='r' , color='cyan' , label='experiment #1' )
plt.xlabel('# measurement' )
plt.ylabel('Measured values' )
plt.title('Measurements' )
plt.legend(loc='upper left' )
plt.show()
9. 让饼图有价值 from pylab import *
figure(1 , figsize=(6 , 6 ))
ax = axes([0.1 , 0.1 , 0.8 , 0.8 ])
labels = 'Spring' , 'Summer' , 'Autumn' , 'Winter'
x = [15 , 30 , 45 , 10 ]
explode = (0.1 , 0.1 , 0.1 , 0.1 )
pie(x, explode=explode, labels=labels, autopct='%1.1f%%' , startangle=67 )
title('Rainy days by season' )
show()
10. 绘制填充区域 from matplotlib.pyplot import figure, show, gca
import numpy as np
x = np.arange(0.0 , 2 , 0.01 )
y1 = np.sin(2 *np.pi*x)
y2 = 1.2 *np.sin(4 *np.pi*x)
fig = figure()
ax = gca()
ax.plot(x, y1, x, y2, color='black' )
ax.fill_between(x, y1, y2, where=y2>=y1, facecolor='darkblue' , interpolate=True )
ax.fill_between(x, y1, y2, where=y2<=y1, facecolor='deeppink' , interpolate=True )
ax.set_title('filled between' )
show()
11. 用彩色标记绘制散点图 import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000 )
y1 = np.random.randn(len (x))
y2 = 1.2 + np.exp(x)
ax1 = plt.subplot(121 )
plt.scatter(x, y1, color='indigo' , alpha=0.3 , edgecolors='white' , label='no correl' )
plt.xlabel('no correlation' )
plt.grid(True )
plt.legend()
ax2 = plt.subplot(122 , sharey=ax1, sharex=ax1)
plt.scatter(x, y2, color='green' , alpha=0.3 , edgecolors='grey' , label='correl' )
plt.xlabel('strong correlation' )
plt.grid(True )
plt.legend()
plt.show()
通过上述步骤,你可以快速搭建 Python 数据可视化环境,掌握多种数据格式的读取与清洗方法,并利用 Matplotlib 绘制出专业且美观的图表。在实际项目中,根据具体需求调整代码细节即可。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online