自学用,综合整理了以下资料:
- 论文画图工具:25个常用Matplotlib图的Python代码总结
- matplotlib常用绘制图的代码总结
- Matplotlib全部基础可视化图形及实现代码(共11种图形)
- 利用python进行数据分析—七、绘图与可视化—matplotlib与seaborn
导入包和初始设置
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import warnings; warnings.filterwarnings(action='once')
large = 22; med = 16; small = 12
params = {'axes.titlesize': large,
'legend.fontsize': med,
'figure.figsize': (16, 10),
'axes.labelsize': med,
'axes.titlesize': med,
'xtick.labelsize': med,
'ytick.labelsize': med,
'figure.titlesize': large}
plt.rcParams.update(params)
plt.style.use('seaborn-whitegrid')
sns.set_style("white")
%matplotlib inline
如果无法显示汉字,则:
plt.rcParams['font.sans-serif'] = ['SimHei'] # 替换sans-serif字体
plt.rcParams['axes.unicode_minus'] = False # 解决坐标轴负数的负号显示问题
不同操作类型
基本设置,标题,label,xlim等等
pyplot接口中有xlim方法来控制绘图范围,有xticks方法来控制刻度位置,有xticklabels方法来控制刻度标签,xlabel方法来控制轴标签,title方法来控制标题。
所有的这些方法都会在当前创建的AxesSubplot上生效。这些方法中每一个对应于子图自身的两个方法。
- xlim对应于ax.get_lim与ax.set_lim
- xticks对应于ax.get_xticks与ax.set_xticks
- xticklabels对应于ax.get_xticklabels与ax.set_xticklabels
- xlabel对应于ax.get_xlabel与ax.set_xlabel
- title对应于ax.get_title与ax.set_title
图例是用来区分绘图元素的重要内容。最简单的方式是在plot方法中传入label参数,然后调用plt.legend或者ax.legend方法自动生成图例。其中legend方法中参数loc控制图例的位置。
对于multiple subplots一般情况下,
1)设置 plt.xticks(range(0, 10))只会对最后一个ax起作用。要想作用于所有subplots,要这样:
for ax in axes:
ax.set_xticks(range(0, 10))
2)标题:显示中文方面-在各个子图上要这样:
plt.title('某个子图的中文title', fontproperties='simhei')
plt.suptitle(‘全体子图的中文title’)
3)xticks的旋转方面。例如上面的主副坐标轴的共x轴,要这样:
ax1.set_xticklabels(['str format labels'], rotation=80)
4)添加子图
fig = plt.figure(figsize=(16, 9), dpi=80)
ax1 = fig.add_subplot(1,1,1)
5)设置tick lim xlabel text等等
plt.xticks( np.arange(1, 11, 1)) # x-tick刻度
plt.yticks(np.arange(0, 101, 10)) # y-tick刻度
plt.xlabel(r'x坐标') #x-label
plt.ylabel(r'y坐标') # y-label
plt.xlim(-20,20) #x范围
plt.ylim(0,200) # y范围
plt.title(r'散点图示例')
plt.grid() #网格
plt.text(1, 10, "解释说明", weight="bold", color="r", fontsize=20, verticalalignment='bottom',
horizontalalignment="center") # 标注
plt.annotate("未达标平均线", xy=(1, 80), arrowprops=dict(arrowstyle="<->"), fontsize=20, xytext=(1, 60)) #箭头
plt.axhline(80, linestyle="--", color="r", label="80%水平线", ) #值为80的水平线
plt.axvline(30,color="r",label="平均线",linestyle=":") #值为30的竖直线
plt.axhspan(ymin=2.6, ymax=3.4,alpha=0.3) # 纵向范围为2.6到3.4的水平区域
plt.axvspan(xmin=40, xmax=46,alpha=0.3) # 横向范围为40到46的竖直区域
plt.legend(loc="upper left", fontsize=20)
plt.show()
fig, ax = plt.subplots(1, 1)
ax2 = ax.twinx() # 让2个子图的x轴一样,同时创建副坐标轴。
fig,ax = plt.subplots()的使用
- pylab和pyplot有当前的图形(figure)和当前的轴(axes)的概念,所有的作图命令都是对当前的对象作用。可以通过gca()获得当前的轴(axes),通过gcf()获得当前的图形(figure)。
- fig, ax = plt.subplots()是用来创建 总画布/figure“窗口”的,有figure就可以在上边(或其中一个子网格/subplot上)作图了,(fig:是figure的缩写)。
- plt.subplot(111)是plt.subplot(1, 1, 1)另一个写法而已,更完整的写法是plt.subplot(nrows=1, ncols=1, index=1)
- fig, ax = plt.subplots()等价于fig, ax = plt.subplots(11)
- fig, axes = plt.subplots(2, 3):即表示一次性在figure上创建成2*3的网格,使用plt.subplot()只能一个一个的添加
- fig代表绘图窗口(Figure);ax代表这个绘图窗口上的坐标系(axis),一般会继续对ax进行操作。
fig, ax = plt.subplots()等价于:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
fig,ax = plt.subplots():建立一个fig对象和一个axis对象
在不同子图绘图时两种选择:
- 选定不同子图axis绘图
fig,ax = plt.subplots(2,2,figsize=(9,25))
# 选定第一个子图
ax1 = plt.subplot(221)
ax1.plot(x1,y1)
# 选定第二个子图
ax2 = plt.subplot(222)
ax2.plot(x2,y2)
- 使用索引绘图
fig,ax = plt.subplots(2,2,figsize=(9,25))
ax[1].plot(x1,y1)
ax[2].plot(x2,y2)
plt.subplot的使用
plt.figure()生成一个空白图片,figsize设置图片的大小,想要在空白图片上进行绘图,使用add_subplot()创建一个或多个子图。
不同绘图类型
1. 散点图
Scatteplot是用于研究两个变量之间关系的经典和基本图。如果数据中有多个组,则可能需要以不同颜色可视化每个组。
# Import dataset
midwest = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/midwest_filter.csv")
# Prepare Data
# Create as many colors as there are unique midwest['category']
categories = np.unique(midwest['category'])
colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
# Draw Plot for Each Category
plt.figure(figsize=(16, 10), dpi= 80, facecolor='w', edgecolor='k')
for i, category in enumerate(categories):
plt.scatter('area', 'poptotal',
data=midwest.loc[midwest.category==category, :],
s=20, c=colors[i], label=str(category))
# Decorations
plt.gca().set(xlim=(0.0, 0.1), ylim=(0, 90000),
xlabel='Area', ylabel='Population')
plt.xticks(fontsize=12); plt.yticks(fontsize=12)
plt.title("Scatterplot of Midwest Area vs Population", fontsize=22)
plt.legend(fontsize=12)
plt.show()
2. 折线图
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(16, 9), dpi=80)
plt.rcParams["font.sans-serif"] = ["SimHei"]
x = np.arange(1, 11, 1)
y_ticks = np.arange(0, 101, 10)
y = np.random.randint(1, 100, size=(10))
y_2 = np.random.randint(1, 100, size=(10))
plt.plot(x, y, label="最高标准")
plt.plot(x, y_2, label="最低标准", color="r")
plt.xticks(x)
plt.yticks(y_ticks)
plt.ylim(0, 110)
plt.xlim(0, 11)
plt.xlabel("x轴")
plt.ylabel("y轴")
plt.title("折线图")
plt.text(1, 10, "解释说明")
plt.legend()
plt.show()
3.柱状图
import matplotlib.pyplot as plt
import numpy as np
y = np.arange(10, 101, 10)
x = np.arange(1, 11)
label = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.figure(figsize=(16, 9), dpi=80)
plt.bar(x, y, width=0.5, label="完成量", color="#ed5736")
plt.xticks(np.arange(1, 11, 1), label)
plt.title("测试", fontsize=50)
plt.text(1, 10, "10%", weight="bold", color="b", fontsize=20, ha="center", va="bottom")
plt.text(2, 20, "20%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(3, 30, "30%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(4, 40, "40%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(5, 50, "50%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(6, 60, "60%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(7, 70, "70%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(8, 80, "80%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(9, 90, "90%", weight="bold", color="r", fontsize=20, verticalalignment='bottom', horizontalalignment="center")
plt.text(10, 100, "100%", weight="bold", color="r", fontsize=20, verticalalignment='bottom',
horizontalalignment="center")
plt.annotate("未达标平均线", xy=(1, 80), arrowprops=dict(arrowstyle="<->"), fontsize=20, xytext=(1, 60))
plt.ylim(0, 120)
plt.xlim(0, 11)
plt.axhline(80, linestyle="--", color="r", label="80%水平线", )
plt.xlabel("x轴", fontsize=24)
plt.ylabel("y轴", fontsize=24)
plt.legend(loc="upper left", fontsize=20)
plt.grid( axis="y", )
plt.show()
4. 直方图
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(16, 9), dpi=80)
plt.rcParams["font.sans-serif"] = ["SimHei"]
x=np.random.randint(0,100,100)
y=np.arange(0,100,10)
plt.hist(x,y)
plt.show()
5.堆积条形图
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体
y = np.arange(5)
x = np.array([16, 8, 22, 44, 36])
y1 = np.arange(0,5,1)
x1 = np.arange(0,101,20)
xerr = np.array(5)
error =[1,2,3,4,5]
name = np.array(["电影一","电影二","电影三","电影四","电影五"])
plt.barh(y, x,height=0.3,label= "动作电影票房",color="#ed5736")
plt.barh(y, x,height=0.3,label= "喜剧电影票房",color="k",xerr=error,left=x)
plt.yticks(y1, name)
plt.xticks(x1)
plt.xlim(0,100)
plt.xlabel("总票房")
plt.ylabel("电影名称")
plt.title("电影票房总收入")
plt.axvline(30,0,1,color="r",label="平均线",linestyle=":")
plt.grid(axis="x", label="网格线")
plt.axhspan(ymin=2.6, ymax=3.4,alpha=0.3)
plt.axvspan(xmin=40, xmax=46,alpha=0.3)
plt.legend()
plt.show()
6. 面积图
import matplotlib.pyplot as plt
import numpy as np
ran1=np.random.randint(1,20,size=10)
ran2=np.random.randint(1,30,size=10)
ran3=np.random.randint(1,20,size=10)
x= np.arange(0,10,1)
plt.figure(figsize=(16, 9), dpi=80)
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.stackplot(x,ran1,)
plt.stackplot(x,ran2,)
plt.stackplot(x,ran3,)
plt.xlim(0,10)
plt.show()
7.箱型图
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(16, 9), dpi=80)
plt.rcParams["font.sans-serif"] = ["SimHei"]
data=np.random.randn(100)
plt.boxplot(data,meanline=True,widths=0.1,showfliers=False,patch_artist=True)
plt.show()
8.误差棒图
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(16, 9), dpi=80)
plt.rcParams["font.sans-serif"] = ["SimHei"]
x =np.arange(5)
y= (25,32,34,20,25)
y_offest=(3,5,2,3,3)
plt.errorbar(x,y,yerr=y_offest,capsize=5,capthick=5)
plt.show()
9.雷达图
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(16, 9), dpi=80)
plt.rcParams["font.sans-serif"] = ["SimHei"]
data =np.random.rand(6,6)
# rradar_labels=["研究型(I)","艺术性(A)","社会性(S)","企业性(E)","传统性(C)","现实性(R)"]
# radar_labels= np.concatenate((radar_labels,[radar_labels[0]]))
anghles=np.linspace(0,2*np.pi,6,endpoint=False)
anghles = np.concatenate((anghles,[anghles[0]]))
data=np.concatenate((data,[data[0]]))
plt.polar(anghles,data)
plt.thetagrids((anghles*180/np.pi))
plt.fill(anghles,data,alpha=0.25)
plt.show()
10.带线性回归最佳拟合线的散点图
# Import Data
df = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/mpg_ggplot2.csv")
df_select = df.loc[df.cyl.isin([4,8]), :]
# Plot
sns.set_style("white")
gridobj = sns.lmplot(x="displ", y="hwy", hue="cyl", data=df_select,
height=7, aspect=1.6, robust=True, palette='tab10',
scatter_kws=dict(s=60, linewidths=.7, edgecolors='black'))
# Decorations
gridobj.set(xlim=(0.5, 7.5), ylim=(0, 50))
plt.title("Scatterplot with line of best fit grouped by number of cylinders", fontsize=20)
11.计数图
避免点重叠问题的另一个选择是增加点的大小,这取决于该点中有多少点。因此,点的大小越大,周围的点的集中度就越大。
# Import Data
df = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/mpg_ggplot2.csv")
df_counts = df.groupby(['hwy', 'cty']).size().reset_index(name='counts')
# Draw Stripplot
fig, ax = plt.subplots(figsize=(16,10), dpi= 80)
sns.stripplot(df_counts.cty, df_counts.hwy, size=df_counts.counts*2, ax=ax)
# Decorations
plt.title('Counts Plot - Size of circle is bigger as more points overlap', fontsize=22)
plt.show()
12.边缘直方图
边缘直方图具有沿X和Y轴变量的直方图。这用于可视化X和Y之间的关系以及单独的X和Y的单变量分布。
# Import Data
df = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/mpg_ggplot2.csv")
# Create Fig and gridspec
fig = plt.figure(figsize=(16, 10), dpi= 80)
grid = plt.GridSpec(4, 4, hspace=0.5, wspace=0.2)
# Define the axes
ax_main = fig.add_subplot(grid[:-1, :-1])
ax_right = fig.add_subplot(grid[:-1, -1], xticklabels=[], yticklabels=[])
ax_bottom = fig.add_subplot(grid[-1, 0:-1], xticklabels=[], yticklabels=[])
# Scatterplot on main ax
ax_main.scatter('displ', 'hwy', s=df.cty*4, c=df.manufacturer.astype('category').cat.codes, alpha=.9, data=df, cmap="tab10", edgecolors='gray', linewidths=.5)
# histogram on the right
ax_bottom.hist(df.displ, 40, histtype='stepfilled', orientation='vertical', color='deeppink')
ax_bottom.invert_yaxis()
# histogram in the bottom
ax_right.hist(df.hwy, 40, histtype='stepfilled', orientation='horizontal', color='deeppink')
# Decorations
ax_main.set(title='Scatterplot with Histograms
displ vs hwy', xlabel='displ', ylabel='hwy')
ax_main.title.set_fontsize(20)
for item in ([ax_main.xaxis.label, ax_main.yaxis.label] + ax_main.get_xticklabels() + ax_main.get_yticklabels()):
item.set_fontsize(14)
xlabels = ax_main.get_xticks().tolist()
ax_main.set_xticklabels(xlabels)
plt.show()
13.边缘箱形图
边缘箱图与边缘直方图具有相似的用途。
# Import Data
df = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/mpg_ggplot2.csv")
# Create Fig and gridspec
fig = plt.figure(figsize=(16, 10), dpi= 80)
grid = plt.GridSpec(4, 4, hspace=0.5, wspace=0.2)
# Define the axes
ax_main = fig.add_subplot(grid[:-1, :-1])
ax_right = fig.add_subplot(grid[:-1, -1], xticklabels=[], yticklabels=[])
ax_bottom = fig.add_subplot(grid[-1, 0:-1], xticklabels=[], yticklabels=[])
# Scatterplot on main ax
ax_main.scatter('displ', 'hwy', s=df.cty*5, c=df.manufacturer.astype('category').cat.codes, alpha=.9, data=df, cmap="Set1", edgecolors='black', linewidths=.5)
# Add a graph in each part
sns.boxplot(df.hwy, ax=ax_right, orient="v")
sns.boxplot(df.displ, ax=ax_bottom, orient="h")
# Decorations ------------------
# Remove x axis name for the boxplot
ax_bottom.set(xlabel='')
ax_right.set(ylabel='')
# Main Title, Xlabel and YLabel
ax_main.set(title='Scatterplot with Histograms
displ vs hwy', xlabel='displ', ylabel='hwy')
# Set font size of different components
ax_main.title.set_fontsize(20)
for item in ([ax_main.xaxis.label, ax_main.yaxis.label] + ax_main.get_xticklabels() + ax_main.get_yticklabels()):
item.set_fontsize(14)
plt.show()
14.相关图
直观地查看给定数据帧(或2D数组)中所有可能的数值变量对之间的相关度量。
# Import Dataset
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/mtcars.csv")
# Plot
plt.figure(figsize=(12,10), dpi= 80)
sns.heatmap(df.corr(), xticklabels=df.corr().columns, yticklabels=df.corr().columns, cmap='RdYlGn', center=0, annot=True)
# Decorations
plt.title('Correlogram of mtcars', fontsize=22)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
15.矩阵图
成对图是探索性分析中的最爱,以理解所有可能的数字变量对之间的关系。它是双变量分析的必备工具。
# Load Dataset
df = sns.load_dataset('iris')
# Plot
plt.figure(figsize=(10,8), dpi= 80)
sns.pairplot(df, kind="scatter", hue="species", plot_kws=dict(s=80, edgecolor="white", linewidth=2.5))
plt.show()
# Load Dataset
df = sns.load_dataset('iris')
# Plot
plt.figure(figsize=(10,8), dpi= 80)
sns.pairplot(df, kind="reg", hue="species")
plt.show()
16. 三维图
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)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,cmap=cm.viridis)
plt.show()