使用 matplotlib 绘图
读取数据import pandas as pddata = pd.read_csv("fileName" , sep='\t' , skiprows=2 , names=['x' ,'y' ,'z' ,'T' ])
默认逗号为分隔符,也可以设为 \t
等。 默认自动将第一行作为 index,可以这样调用:data['x']
。 也可以手动设置 index:names=['x','y','z','T']
。 通过 skiprows 设置需要忽略的行:
数字指定:skiprows = 2
表示忽略前 2 行。 列表指定:skiprows = [0]
表示忽略第 0 行。 列表指定:skiprows = range(1, 10))
表示忽略第 1 到 9 行,保留第 0 行,和第 10 行及以后的行。 图型 点线图 plotplot(Z, Y, color='green' , linestyle='dashed' , linewidth=2 , marker='o' , markersize=12 )
官方链接:colors markers Linestyles colormaps
Base Colors
常见 linestyle
unfilled markers filled markers 空心 markers
plt.plot(X, Y, 'o', markerfacecolor='none')
可以将 plot
中的线宽设为 0,这样只剩下 symbol:
plot(X, Y, marker='.' , linewidth=0 )
竖直线和水平线水平线
ax.axhline(y=0 , xmin=0 , xmax=1 , color='black' , linewidth=2 ) ax.axhline(0 , color='black' , linewidth=2 ) plt.axhline(0 , color='black' , linewidth=2 )
竖直线
ax.axvline(x=0 , ymin=0 , ymax=1 , color="r" ) ax.axvline(0 , color="r" ) plt.axvline(0 , color="r" )
散点图 scatterplt.scatter(X, Y, c=Z, s=1 , marker='s' , cmap=plt.cm.hot)
散点用 X Y 表示,用 Z 着色,色带是 plt.cm.hot,size 是 1。更多设置参考网址
如果要对散点着色的话,建议先将所有点按照 Z 排序:
idx = Z.argsort() X, Y, Z = X[idx], Y[idx], Z[idx]
绘制界限分明的 colorbar官方链接
记得选用 diverging 色条,比如官方的 seismic 。
divnorm = colors.TwoSlopeNorm(vcenter=0) plt.scatter(X, Y, c=Z, norm=divnorm,cmap=matplotlib.cm.seismic)
云图 contourfdata = pd.read_csv("fileName" , sep='\t' ) X = data['X' ] Y = data['Y' ] Z = data['Z' ] xi=np.linspace(min (X),max (X),1000 ) yi=np.linspace(min (Y),max (Y),1000 ) [XX,YY]=np.meshgrid(xi,yi) ZZ=griddata((X,Y), Z, (XX,YY), method='cubic' ) plt.contourf(XX, YY, ZZ, 20 , cmap=plt.cm.hot) cbar = plt.colorbar()
还有一种更简便的方法:
plt.tricontourf(X, Y, Z, 20 , cmap=plt.cm.hot, extend='both' )
手动指定 levels 越界时指定颜色extend : {'neither', 'both', 'min', 'max'}
,默认值是 neither
levels=np.arange(-10 ,4200000 ,1000 ) cp=plt.contourf(XX, YY, ZZ, levels=levels, cmap=plt.cm.hot, extend='both' ) cp.cmap.set_under('yellow' ) cp.cmap.set_over('cyan' ) cbar = plt.colorbar(cp) cbar.ax.set_title('T' )
越界时为空白举例:小于某个数时颜色全部为空白(假设原始数据的大小是 0~0.75) 那么图片里边,小于 0.0015 的区域,都将是空白
levels=np.arange(0.0015 ,0.7515 ,0.0015 ) plt.contourf(XX, YY, ZZ,levels=levels)
设置图中的数值上下限:
设置 colorbar 中的上下限:
log:https://matplotlib.org/3.1.1/gallery/images_contours_and_fields/contourf_log.html
等值线plt.contourf(XX, YY, ZZ, 20 , cmap=plt.cm.hot) plt.contour(XX, YY, ZZ, 1 , levels=[1000 ], linewidths=2 , colors='y' )
配件 图片颜色colorMap = plt.cm.get_cmap('winter' ) colorMap=plt.get_cmap("YlOrRd" ) colorMap=pyplot.cm.jet
源码:https://github.com/jiffyclub/palettable
from palettable.mycarta import Cube1_20from palettable.colorbrewer.sequential import Greys_9colorMap=Cube1_20.mpl_colormap colorMap=Greys_9.mpl_colormap
源码:https://github.com/pyviz/colorcet
import colorcet as cccolorMap=cc.cm["blues" ] colorMap=cc.cm["fire" ]
反转颜色自带的反转就是在后边加一个 _r
,比如:colorMap=plt.cm.hot_r
。
反转非自带的颜色:
def reverse_colourmap (cmap, name = 'my_cmap_r' ): """ In: cmap, name Out: my_cmap_r Explanation: t[0] goes from 0 to 1 row i: x y0 y1 -> t[0] t[1] t[2] / / row i+1: x y0 y1 -> t[n] t[1] t[2] so the inverse should do the same: row i+1: x y1 y0 -> 1-t[0] t[2] t[1] / / row i: x y1 y0 -> 1-t[n] t[2] t[1] """ reverse = [] k = [] for key in cmap._segmentdata: k.append(key) channel = cmap._segmentdata[key] data = [] for t in channel: data.append((1 -t[0 ],t[2 ],t[1 ])) reverse.append(sorted (data)) LinearL = dict (zip (k,reverse)) my_cmap_r = mpl.colors.LinearSegmentedColormap(name, LinearL) return my_cmap_r cmap=cc.cm["fire" ] cmap_r = reverse_colourmap(cmap)
colorbar 官方 APIAPI API2
简单使用sc = plt.scatter(X, Y, c=Z, s=1 , cmap=pyplot.cm.jet) plt.colorbar(sc)
位置偏移使用 pad,尺寸缩小使用 shrink
plt.colorbar(sc, pad = 0.07 , shrink=0.8 )
坐标控制的位置cbar_ax = fig.add_axes([0.19 , 0.06 , 0.7 , 0.015 ]) cbar=plt.colorbar(sc, cax=cbar_ax, orientation='horizontal' )
set_ticks手动设置坐标
cbar_ticks = np.linspace(0. , 5e-3 , num=3 , endpoint=True ) cbar.set_ticks(cbar_ticks)
怎么才能在坐标上显示 max min? 科学计数法cbar.formatter.set_powerlimits((-1 , 1 )) cbar.update_ticks()
这样小于 10^(-1),或者大于 10^(1) 的值就会用科学计数法。
ticks 朝向如果 colorbar 竖直,ticks 默认是朝右的,如果 colorbar 水平,ticks 默认朝下的。
可以这样更改:
cbar.ax.xaxis.set_ticks_position('top' ) cbar.ax.yaxis.set_ticks_position('left' )
也可以这样:
cbar.ax.yaxis.tick_left()
添加变量名 set_titleset_title set_title
默认在最上方,不管 colorbar 是水平还是竖直。 有个参数 pad 表示向上偏移距离,但是 pad 等于负数时无效。
cbar.ax.set_title('$\Omega\ [-]$' , pad=10 )
添加变量名 set_label推荐使用 set_label
cbar.set_label('$\Omega\ [-]$' ) cbar.set_label(r"$\Delta$" +varName, va='bottom' , ha='right' , labelpad=10 )
变量名改变位置colorbar 是水平的,这里的 bottom 表示变量名放在水平 colorbar 的下边,labelpad 是向下的偏移距离。
cbar.set_label('T' ,verticalalignment='bottom' , labelpad=-10 )
Vertical alignment must be one of (‘top’, ‘bottom’, ‘center’, ‘baseline’) Horizontal alignment must be one of (‘center’, ‘right’, ‘left’)
对于水平 colorbar,horizontalalignment
不管用?
图例 legendplt.plot(X, Y, label="sim" ) plt.legend(loc='upper left' ) plt.legend(loc='best' ) plt.plot(legend=None )
上下左右中:upper lower left right
还有一个中,可以是上下的中,也可以是左右的中:center
有这些组合:
best upper right upper left lower left lower right right center left center right lower center upper center center
在循环里边画很多条线时,只想保留一个 legend,循环结束后:
from collections import OrderedDict handles, labels = plt.gca().get_legend_handles_labels() by_label = OrderedDict(zip(labels, handles)) plt.legend(by_label.values(), by_label.keys())
缩放图例中的 marker 大小: markerscale Default is None, which will take the value from rcParams[“legend.markerscale”] = 1.0.
plt.legend(loc='upper right',markerscale=3,fancybox=True, framealpha=0.1)
缩放图例中的线宽
leg = ax.legend() for line in leg.get_lines(): line.set_linewidth(4.0)
关于位置的高级用法:
ax1.legend(loc='upper right' , bbox_to_anchor=(1.05 , 4.3 ), ncol=3 , fontsize=10 )
bbox_to_anchor
表示 right 和 upper 的位置。 upper right 和 loc 里的一致,不过顺序颠倒了,这里表示图例的 right 位于主图的 1.05,图例的 upper 位于主图的 4.3。 这个位置是 0-1,超过 1 表示坐标轴以外。ncol=3
表示三栏
保存为图片后,如果图例超出了整个图片的范围,则可以这样操作:
lgd =plt.legend(loc='center left' , bbox_to_anchor=(1 , 0.5 )) plt.savefig("fig.png" , bbox_extra_artists=(lgd,), bbox_inches='tight' )
如果图例分了多列,columnspacing=2.0
控制列之间的间隔。handletextpad=0.8
可以控制 marker 和 label 之间的间隔。参考资料
坐标轴 设置坐标轴 labelplt.xlabel('r [mm]' ,fontsize=12 ) ax.set_xlabel('r [mm]' ,fontsize=12 )
调整坐标轴范围plt.axis([0 , 4 , 0 , 4 ]) plt.axis(xmin =0 , xmax = 0.5 , ymin = 0 , ymax = 0.55 ) plt.xlim(0 ,0.35 ) plt.ylim(0 ,0.2 )
自定义刻度x_new=np.array([5 ,10 ,15 ,20 ]) plt.xticks(x_new)
刻度朝内plt.tick_params(direction='in' )
刻度小数点位数import matplotlib.ticker as tickerplt.gca().xaxis.set_major_formatter(ticker.FormatStrFormatter('%.6f' ))
隐藏坐标在包含几个子图的图标中,可能需要隐藏一些重复的坐标
ax1 = plt.subplot(420 +i) plt.setp(ax1.get_xticklabels(), visible=False ) plt.setp(ax1.get_yticklabels(), visible=False )
隐藏 ticks 和 label 隐藏子刻度 科学计数plt.ticklabel_format(axis="x" , style="sci" , scilimits=(0 ,0 )) ax.ticklabel_format(axis="x" , style="sci" , scilimits=(0 ,0 ))
对数坐标plt.xscale('log') ax.set_xscale('log')
可选项 : {“linear”, “log”, “symlog”, “logit”, …}
x y 坐标等比例这个用于 CFD 模拟场的云图,保证 x y 长度是等比例的。
ax=plt.gca() ax.set_aspect(1.0 )
使用 LaTeX 公式用 $
包围起来并在前边加上 r
即可,最好 $
和公式之间留一个空格。
plt.xlabel(r'Scalar dissipation rate $ [s^{-1}] $' )
任意位置添加文字text
标注可以附带箭头annotate 示例:
子图 subplotplt.subplots_adjust(left=0.11 ,bottom=0.1 ,top=0.97 ,right=0.9 ,hspace=0.000001 ,wspace=0.000001 ) i=0 for Z in ['2' ,'10' ,'30' ,'50' ]: i=i+1 ax = plt.subplot(410 +i) ax.plot(R_Mean,U_Mean,linestyle='--' ,marker='o' , color='r' ,label="sim" )
subplot(410+i)
表示子图 4x1 排列,即 4 行 1 列。此处的循环,令 i
分分别等于 1 2 3 4。
也可以用 subplot(4,1,i)
表示。
绘制着色的多个子图(云图或者上色 = 的散点图)需要注意他们的数据 min max 可能不同。 可以设置 vmin vmax 是他们保持一致:
plt.scatter(x1, y1, c=z1, s=2, marker='o', vmin=minZ, vmax=maxZ) plt.scatter(x2, y2, c=z2, s=2, marker='s', vmin=minZ, vmax=maxZ)
图片标题plt.title('source_Yc' ,fontsize=12 )
alpha 表示不透明度,1 表示完全不透明可以用于 plot scatter contour contourf 中。
输出图片 紧凑布局plt.savefig("abc.png" , dpi=500 , bbox_inches='tight' , pad_inches=0.01 ) plt.savefig("abc.pdf" , bbox_inches='tight' , pad_inches=0.01 ) plt.close() fig = plt.figure() fig.savefig("abc.png" , dpi=500 , bbox_inches='tight' , pad_inches=0.01 ) fig.savefig("abc.pdf" , bbox_inches='tight' , pad_inches=0.01 ) fig.close()
python 相关 利用正则表达式获取当前目录下的某些文件import globfiles = glob.iglob(r'0.*' ) for file in files: print file
普通版本:
files = ['0.1' , '0.2' ] for file in files: print file
换行ylabel('this is vertical\ntest' , multialignment='center' )
灰色系列填充彩图 在图中使用其它字体https://stackoverflow.com/a/53645383 我成功操作的经历:
把字体拷贝到: /public/home/yao1/packages_ZY/anaconda_ZY/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf 然后: rm -rf ~/.cache/matplotlib/
使用字体:
from matplotlib import rcParamsrcParams.update({'font.size' : 12 , 'font.family' : 'Times New Roman' }) from matplotlib import rcParamsrcParams.update({'font.size' : 12 , 'font.family' : 'simsun' }) ax.legend(loc='upper right' , bbox_to_anchor=(0.92 , 3.7 ), ncol=3 ,fontsize=10 ,prop={'family' :'simsun' }) plt.text(1.03 ,5.4 ,'平均值' ,fontname='simsun' )
疑难解答 服务器绘图报错 QXcbConnection: Could not connect to display
solution: 在脚本的 ** 最前边 ** 加上
import matplotlibmatplotlib.use('Agg' )
范例散点图,另外用颜色表示散点密度
def density_scatter (x, y, ax=None , sort=True , bins=20 , **kwargs ): """ Scatter plot colored by 2d histogram """ from scipy.interpolate import interpn if ax is None : fig, ax = plt.subplots() data, x_e, y_e = np.histogram2d(x, y, bins=bins) z = interpn((0.5 *(x_e[1 :] + x_e[:-1 ]), 0.5 *(y_e[1 :]+y_e[:-1 ])), data, np.vstack([x,y]).T, method="splinef2d" , bounds_error=False ) if sort : idx = z.argsort() x, y, z = x[idx], y[idx], z[idx] ax.scatter(x, y, c=z) return ax cax=density_scatter(x, y, bins = [50 ,50 ]) from scipy.stats import gaussian_kdexy = np.vstack([x,y]) z = gaussian_kde(xy)(xy) plt.scatter(x, y,c=z, s=100 , edgecolor='' ) plt.colorbar()