数学建模程序部分之绘图可视化 计划实现语言:python¶
参考https://zhuanlan.zhihu.com/p/347717545¶
https://matplotlib.org/stable/gallery/index.html¶
In [6]:
import matplotlib.pyplot as plt #调用pyplot,以这个包为基础应该能满足数学建模基础作图要求
x = [1, 2, 3, 4, 5]
y = [2.3, 3.4, 1.2, 6.6, 7.0]
plt.scatter(x, y, color='r', marker='+')#这里颜色和线型都可以调整,我们可以提前确定一下作图风格
Out[6]:
In [8]:
# https://www.runoob.com/w3cnote/matplotlib-tutorial.html
#这里有非常详尽的基本图像调节指南↑import numpy as np#numpy不是绘图的库嗷,是以矩阵为基础的数学计算模块,在数据处理的时候非常常见X = np.linspace(-np.pi, np.pi, 256, endpoint=True)#这里在规定范围,从− −π到 π线性分割出256份
C,S = np.cos(X), np.sin(X)C = C + np.random.rand(256)*0.2#这里是加了个随机噪声,稍微复杂一下图像案例
S = S + np.random.rand(256)*0.4
plt.rcParams['figure.dpi'] = 100 #好像是设置点间密度用的plt.plot(X,C)
plt.plot(X,S)# 以分辨率 72 来保存图片
# savefig("exercice_2.png",dpi=72)plt.show()#如果想要更改线型颜色,也ok
# help(plt.plot)
# 提示:使用help(plt.plot)以查看帮助文档,这非常有用plt.plot(X,C, 'gs--', linewidth=0.8,markersize=2)
plt.plot(X,S,color="red",marker="1", linewidth=0.4, linestyle="-")plt.show()
关于以上实例的进一步说明¶
我们还可以在他的基础上改变坐标轴大小和画布的尺寸,
调整坐标的分度值,
移动坐标轴在画面中的位置,
调整透明度,
增加图例,
标注特别的点
作为提纲指南,此处不一一展示,需要时见以上两个网址即可
进阶使用¶
在matplotlib中还有海量图示可以使用,我尝试通读一遍example,并扒出我认为可能用到的(或者只是花里胡哨的)进一步说明。
按惯例,需要时借鉴https://matplotlib.org/stable/gallery/index.html 官网案例即可。
Lines, bars and markers¶
来几个柱形图
In [25]:
N = 5
menMeans = (20, 35, 30, 35, -27)
womenMeans = (25, 32, 34, 20, -25)
menStd = (2, 3, 4, 1, 2)
womenStd = (3, 5, 2, 3, 3)
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars: can also be len(x) sequencefig, ax = plt.subplots()p1 = ax.bar(ind, menMeans, width, yerr=menStd, label='Men')
p2 = ax.bar(ind, womenMeans, width,bottom=menMeans, yerr=womenStd, label='Women')ax.axhline(0, color='grey', linewidth=0.8)
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(ind)
ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))
ax.legend()# Label with label_type 'center' instead of the default 'edge'
#ax.bar_label(p1, label_type='center')#!!!!!这里出现问题导致数字显示不出来
#ax.bar_label(p2, label_type='center')
#ax.bar_label(p2)
plt.show()
In [24]:
#制作一组数据的直方图
labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]x = np.arange(len(labels)) # the label locations
width = 0.35 # the width of the barsfig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()#ax.bar_label(rects1, padding=3)
#ax.bar_label(rects2, padding=3)fig.tight_layout()plt.show()
可以画曲线的误差带
可以做填充
可以对缺失数据做mask
可以把一条线画出多种颜色(根据折线所表示数值的高低变化)
可以绘制平面中心为散点图,两侧为直方图
Statistics¶
箱型图部分
In [16]:
from matplotlib.patches import Polygon# Fixing random state for reproducibility
np.random.seed(19680801)# fake up some data
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low))fig, axs = plt.subplots(2, 3)# basic plot基础图样
axs[0, 0].boxplot(data)
axs[0, 0].set_title('basic plot')# notched plot缺口图
axs[0, 1].boxplot(data, 1)
axs[0, 1].set_title('notched plot')# change outlier point symbols改一下外部点的形状(改的好丑)
axs[0, 2].boxplot(data, 0, 'gD')
axs[0, 2].set_title('change outlier\npoint symbols')# don't show outlier points不显示外部点
axs[1, 0].boxplot(data, 0, '')
axs[1, 0].set_title("don't show\noutlier points")# horizontal boxes水平箱子
axs[1, 1].boxplot(data, 0, 'rs', 0)
axs[1, 1].set_title('horizontal boxes')# change whisker length没看懂改了个啥
axs[1, 2].boxplot(data, 0, 'rs', 0, 0.75)
axs[1, 2].set_title('change whisker length')fig.subplots_adjust(left=0.08, right=0.98, bottom=0.05, top=0.9,hspace=0.4, wspace=0.3)# fake up some more data多做几组数据
spread = np.random.rand(50) * 100
center = np.ones(25) * 40
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
d2 = np.concatenate((spread, center, flier_high, flier_low))
# Making a 2-D array only works if all the columns are the
# same length. If they are not, then use a list instead.
# This is actually more efficient because boxplot converts
# a 2-D array into a list of vectors internally anyway.
data = [data, d2, d2[::2]]# Multiple box plots on one Axes
fig, ax = plt.subplots()
ax.boxplot(data)plt.show()
In [17]:
#让我们再学习一种新的图示,小提琴图(具体含义见辅助图片)
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(9, 4))# Fixing random state for reproducibility
np.random.seed(19680801)# generate some random test data
all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]# plot violin plot
axs[0].violinplot(all_data,showmeans=False,showmedians=True)
axs[0].set_title('Violin plot')# plot box plot
axs[1].boxplot(all_data)
axs[1].set_title('Box plot')# adding horizontal grid lines
for ax in axs:ax.yaxis.grid(True)ax.set_xticks([y + 1 for y in range(len(all_data))])ax.set_xlabel('Four separate samples')ax.set_ylabel('Observed values')# add x-tick labels
plt.setp(axs, xticks=[y + 1 for y in range(len(all_data))],xticklabels=['x1', 'x2', 'x3', 'x4'])
plt.show()
二者比较:By default, box plots show data points outside 1.5 * the inter-quartile range as outliers above or below the whiskers whereas violin plots show the whole range of the data.
In [18]:
#画一个简单的直方图
N_points = 100000
n_bins = 20# Generate a normal distribution, center at x=0 and y=5
x = np.random.randn(N_points)
y = .4 * x + np.random.randn(100000) + 5fig, axs = plt.subplots(1, 2, sharey=True, tight_layout=True)# We can set the number of bins with the `bins` kwarg
axs[0].hist(x, bins=n_bins)
axs[1].hist(y, bins=n_bins)
Out[18]:
(array([3.0000e+00, 1.5000e+01, 6.8000e+01, 2.7600e+02, 9.7300e+02,2.5810e+03, 5.7930e+03, 1.0381e+04, 1.5125e+04, 1.7911e+04,1.7295e+04, 1.3550e+04, 8.6630e+03, 4.6030e+03, 1.8770e+03,6.4000e+02, 1.9900e+02, 3.8000e+01, 7.0000e+00, 2.0000e+00]),array([ 0.15026293, 0.64387908, 1.13749522, 1.63111136, 2.12472751,2.61834365, 3.11195979, 3.60557594, 4.09919208, 4.59280822,5.08642437, 5.58004051, 6.07365665, 6.5672728 , 7.06088894,7.55450508, 8.04812123, 8.54173737, 9.03535351, 9.52896966,10.0225858 ]),<a list of 20 Patch objects>)
In [26]:
#如果你想瞎搞直方图的话
np.random.seed(19680801)n_bins = 10
x = np.random.randn(1000, 3)fig, ((ax0, ax1), (ax2, ax3)) = plt.subplots(nrows=2, ncols=2)colors = ['red', 'tan', 'lime']
ax0.hist(x, n_bins, density=True, histtype='bar', color=colors, label=colors)
ax0.legend(prop={'size': 10})
ax0.set_title('bars with legend')ax1.hist(x, n_bins, density=True, histtype='bar', stacked=True)
ax1.set_title('stacked bar')ax2.hist(x, n_bins, histtype='step', stacked=True, fill=False)
ax2.set_title('stack step (unfilled)')# Make a multiple-histogram of data-sets with different length.
x_multi = [np.random.randn(n) for n in [10000, 5000, 2000]]
ax3.hist(x_multi, n_bins, histtype='bar')
ax3.set_title('different sample sizes')fig.tight_layout()
plt.show()
Pie and polar charts¶
接下来是可爱的饼图(饼图真的很可爱对不对!)
In [28]:
# Pie chart, where the slices will be ordered and plotted counter-clockwise:
#先搞个基础的
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0.2, 0) # only "explode" the 2nd slice (i.e. 'Hogs')我在这里已经修改了一个值了,这个函数就是把每一块和整体划拉开用的fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',shadow=True, startangle=90)
ax1.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.相等的纵横比可确保将饼图绘制为圆形。plt.show()
可以在一侧做柱状图,不演示了就
可以加图例
演示一下嵌套饼图和极坐标上的柱状图(主要是因为好看)
In [29]:
# Fixing random state for reproducibility
np.random.seed(19680801)# Compute pie slices
N = 20
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N)
colors = plt.cm.viridis(radii / 10.)ax = plt.subplot(projection='polar')
ax.bar(theta, radii, width=width, bottom=0.0, color=colors, alpha=0.5)plt.show()
#还可以画极坐标散点图,由于太花里胡哨并且想不到应用场景就算了
In [30]:
fig, ax = plt.subplots()size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])cmap = plt.get_cmap("tab20c")
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap([1, 2, 5, 6, 9, 10])ax.pie(vals.sum(axis=1), radius=1, colors=outer_colors,wedgeprops=dict(width=size, edgecolor='w'))ax.pie(vals.flatten(), radius=1-size, colors=inner_colors,wedgeprops=dict(width=size, edgecolor='w'))#这里的wedgeprops决定了嵌套效果ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()
Text, labels and annotations¶
教你如何画箭头,更改箭头类型
如何用日期做标签
数学文本编辑bulabula,多且用处不大
Pyplot¶
啊,才开始讲绘图吗?
如何调整对齐,如何加标注,如何加线,如何加数学公式,如何加文本
In [31]:
#标注一个局部极大值
fig, ax = plt.subplots()t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),arrowprops=dict(facecolor='black', shrink=0.05),)
ax.set_ylim(-2, 2)
plt.show()
In [35]:
#一起感受一下新功能吧,画3D图
from matplotlib import cm
#from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatterfig = plt.figure()ax = fig.add_subplot(1, 2, 1, projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis,linewidth=0, antialiased=False)
ax.set_zlim3d(-1.01, 1.01)#ax.zaxis.set_major_locator(LinearLocator(10))
#ax.zaxis.set_major_formatter(FormatStrFormatter('%.03f'))fig.colorbar(surf, shrink=0.5, aspect=5)from mpl_toolkits.mplot3d.axes3d import get_test_data
ax = fig.add_subplot(1, 2, 2, projection='3d')
X, Y, Z = get_test_data(0.05)
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)plt.show()
Color¶
Shapes and collections¶
Style sheets¶
Axis Artist¶
顾名思义,以花里胡哨为核心主旨的几个部分。尤其style,就是搞配色的,可以在赛前商量好,以免届时由于审美差异打架。
Axes Grid 轴网格,实在不懂且非常用不到的一个部分¶
Showcase 休息部分,show一下wuli可爱的火狐狐吧¶
In [38]:
import re
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches# From: http://raphaeljs.com/icons/#firefox
firefox = "M28.4,22.469c0.479-0.964,0.851-1.991,1.095-3.066c0.953-3.661,0.666-6.854,0.666-6.854l-0.327,2.104c0,0-0.469-3.896-1.044-5.353c-0.881-2.231-1.273-2.214-1.274-2.21c0.542,1.379,0.494,2.169,0.483,2.288c-0.01-0.016-0.019-0.032-0.027-0.047c-0.131-0.324-0.797-1.819-2.225-2.878c-2.502-2.481-5.943-4.014-9.745-4.015c-4.056,0-7.705,1.745-10.238,4.525C5.444,6.5,5.183,5.938,5.159,5.317c0,0-0.002,0.002-0.006,0.005c0-0.011-0.003-0.021-0.003-0.031c0,0-1.61,1.247-1.436,4.612c-0.299,0.574-0.56,1.172-0.777,1.791c-0.375,0.817-0.75,2.004-1.059,3.746c0,0,0.133-0.422,0.399-0.988c-0.064,0.482-0.103,0.971-0.116,1.467c-0.09,0.845-0.118,1.865-0.039,3.088c0,0,0.032-0.406,0.136-1.021c0.834,6.854,6.667,12.165,13.743,12.165l0,0c1.86,0,3.636-0.37,5.256-1.036C24.938,27.771,27.116,25.196,28.4,22.469zM16.002,3.356c2.446,0,4.73,0.68,6.68,1.86c-2.274-0.528-3.433-0.261-3.423-0.248c0.013,0.015,3.384,0.589,3.981,1.411c0,0-1.431,0-2.856,0.41c-0.065,0.019,5.242,0.663,6.327,5.966c0,0-0.582-1.213-1.301-1.42c0.473,1.439,0.351,4.17-0.1,5.528c-0.058,0.174-0.118-0.755-1.004-1.155c0.284,2.037-0.018,5.268-1.432,6.158c-0.109,0.07,0.887-3.189,0.201-1.93c-4.093,6.276-8.959,2.539-10.934,1.208c1.585,0.388,3.267,0.108,4.242-0.559c0.982-0.672,1.564-1.162,2.087-1.047c0.522,0.117,0.87-0.407,0.464-0.872c-0.405-0.466-1.392-1.105-2.725-0.757c-0.94,0.247-2.107,1.287-3.886,0.233c-1.518-0.899-1.507-1.63-1.507-2.095c0-0.366,0.257-0.88,0.734-1.028c0.58,0.062,1.044,0.214,1.537,0.466c0.005-0.135,0.006-0.315-0.001-0.519c0.039-0.077,0.015-0.311-0.047-0.596c-0.036-0.287-0.097-0.582-0.19-0.851c0.01-0.002,0.017-0.007,0.021-0.021c0.076-0.344,2.147-1.544,2.299-1.659c0.153-0.114,0.55-0.378,0.506-1.183c-0.015-0.265-0.058-0.294-2.232-0.286c-0.917,0.003-1.425-0.894-1.589-1.245c0.222-1.231,0.863-2.11,1.919-2.704c0.02-0.011,0.015-0.021-0.008-0.027c0.219-0.127-2.524-0.006-3.76,1.604C9.674,8.045,9.219,7.95,8.71,7.95c-0.638,0-1.139,0.07-1.603,0.187c-0.05,0.013-0.122,0.011-0.208-0.001C6.769,8.04,6.575,7.88,6.365,7.672c0.161-0.18,0.324-0.356,0.495-0.526C9.201,4.804,12.43,3.357,16.002,3.356z"def svg_parse(path):commands = {'M': (Path.MOVETO,),'L': (Path.LINETO,),'Q': (Path.CURVE3,)*2,'C': (Path.CURVE4,)*3,'Z': (Path.CLOSEPOLY,)}vertices = []codes = []cmd_values = re.split("([A-Za-z])", path)[1:] # Split over commands.for cmd, values in zip(cmd_values[::2], cmd_values[1::2]):# Numbers are separated either by commas, or by +/- signs (but not at# the beginning of the string).points = ([*map(float, re.split(",|(?<!^)(?=[+-])", values))] if valueselse [(0., 0.)]) # Only for "z/Z" (CLOSEPOLY).points = np.reshape(points, (-1, 2))if cmd.islower():points += vertices[-1][-1]codes.extend(commands[cmd.upper()])vertices.append(points)return np.array(codes), np.concatenate(vertices)# SVG to Matplotlib
codes, verts = svg_parse(firefox)
path = Path(verts, codes)xmin, ymin = verts.min(axis=0) - 1
xmax, ymax = verts.max(axis=0) + 1fig = plt.figure(figsize=(5, 5), facecolor="0.75") # gray background
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1,xlim=(xmin, xmax), # centeringylim=(ymax, ymin), # centering, upside downxticks=[], yticks=[]) # no ticks# White outline (width = 6)
ax.add_patch(patches.PathPatch(path, facecolor='blue', edgecolor='w', lw=6))
# Actual shape with black outline
ax.add_patch(patches.PathPatch(path, facecolor='red', edgecolor='k', lw=2))plt.show() # Display
Animation 论文不是预言家日报,动不起来¶
Event handling,Front Page,Miscellaneous跳¶
3D plotting¶
In [42]:
#柱状3D图
# setup the figure and axes
fig = plt.figure(figsize=(8, 3))
ax1 = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122, projection='3d')# fake data
_x = np.arange(4)
_y = np.arange(5)
_xx, _yy = np.meshgrid(_x, _y)
x, y = _xx.ravel(), _yy.ravel()top = x + y
bottom = np.zeros_like(top)
width = depth = 1ax1.bar3d(x, y, bottom, width, depth, top, shade=True)
ax1.set_title('Shaded')ax2.bar3d(x, y, bottom, width, depth, top, shade=False)
ax2.set_title('Not Shaded')plt.show()#但是我确实没想到这个图该怎么理解...
In [51]:
#柱状图三合一变立体
#from mpl_toolkits.mplot3d import Axes3D
# Fixing random state for reproducibility
np.random.seed(19680801)fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')#没搞明白这里为什么要111,网站上原文没有这个会无法通过编译colors = ['r', 'g', 'b', 'y']
yticks = [3, 2, 1, 0]
for c, k in zip(colors, yticks):# Generate the random data for the y=k 'layer'.xs = np.arange(20)ys = np.random.rand(20)# You can provide either a single color or an array with the same length as# xs and ys. To demonstrate this, we color the first bar of each set cyan.cs = [c] * len(xs)cs[0] = 'c'# Plot the bar graph given by xs and ys on the plane y=k with 80% opacity.ax.bar(xs, ys, zs=k, zdir='y', color=cs, alpha=0.8)ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')# On the y axis let's only label the discrete values that we have data for.
ax.set_yticks(yticks)plt.show()
Scales比例调整技巧,Specialty Plots这就不看了¶
Ticks and spines刻度与坐标轴,Units单位¶
Embedding Matplotlib in graphical user interfaces图形用户嵌入,Userdemo,Widgets小样例和工具部分¶
看完了!!!!!matplotlib官网部分的example✿✿ヽ(°▽°)ノ✿,大概三四个小时吧,8.13十点多~8月14日02:16
使用python做数据可视化才刚开了个头,最后用官网的介绍作为结尾:
Gallery
This gallery contains examples of the many things you can do with Matplotlib. Click on any image to see the full image and source code.
For longer tutorials, see our tutorials page. You can also find external resources and a FAQ in our user guide.