pytorch visdom可视化工具学习—1—详细使用-2-plotting绘图
3)plotting绘图
我们已经包装了几种常见的plot类型,以便轻松创建基本的可视化。这些可视化是由Plotly驱动的。
Visdom支持下列API。由 Plotly 提供可视化支持。
- vis.scatter : 2D 或 3D 散点图
- vis.line : 线图
- vis.stem : 茎叶图
- vis.heatmap : 热力图
- vis.bar : 条形图
- vis.histogram: 直方图
- vis.boxplot : 箱型图
- vis.surf : 表面图
- vis.contour : 轮廓图
- vis.quiver : 绘出二维矢量场
- vis.mesh : 网格图
这些API的确切输入类型有所不同,尽管大多数API 的输入包含,一个tensor X(保存数据)和一个可选的tensor Y(保存标签或者时间戳)。所有的绘图函数都接收一个可选参数win,用来将图画到一个特定的Pane上。每个绘图函数也会返回当前绘图的win。您也可以指定绘出的图添加到哪个env上。
Visdom同时支持PyTorch的tensor和Numpy的ndarray两种数据结构,但不支持Python的int、float等类型,因此每次传入时都需先将数据转成ndarray或tensor。上述操作的参数一般不同,但有两个参数是绝大多数操作都具备的:
- win:用于指定pane的名字,如果不指定,visdom将自动分配一个新的pane。如果两次操作指定的win名字一样,新的操作将覆盖当前pane的内容,因此建议每次操作都重新指定win。
- opts:选项,接收一个字典,常见的option包括
title
、xlabel
、ylabel
、width
等,主要用于设置pane的显示格式。
之前提到过,每次操作都会覆盖之前的数值,但往往我们在训练网络的过程中需不断更新数值,如损失值等,这时就需要指定参数update='append'
来避免覆盖之前的数值。
而除了使用update参数以外,还可以使用vis.updateTrace
方法来更新图,但updateTrace
不仅能在指定pane上新增一个和已有数据相互独立的Trace,还能像update='append'
那样在同一条trace上追加数据。
Customizing plots
绘图函数接受一个可选的opts表作为输入,可用于更改绘图的(通用的或特定于绘图的)属性。所有输入参数在一个表中指定;输入参数是基于它们在输入表中拥有的键进行匹配的。
1> plot.scatter
这个函数是用来画2D或3D数据的散点图。它需要输入 N*2或N*3的张量 X来指定N个点的位置。一个可供选择的长度为N的向量用来保存X中的点对应的标签(1 到 K)。 – 标签可以通过点的颜色反应出来。
update可用于有效地更新现有图的数据。使用'append'附加数据,'replace'使用新数据,或'remove'删除按名称指定的跟踪。如果不存在update='append',则使用update='append'将创建一个绘图,否则将追加到现有绘图。如果更新单个跟踪,请使用name指定要更新的跟踪的名称。忽略所有NaN的更新数据(可用于屏蔽更新)。
scatter()支持下列的选项:
- opts.markersymbol: 标记符号 (string; default = 'dot')
- opts.markersize : 标记大小(number; default = '10')
- opts.markercolor : 每个标记的颜色. (torch.*Tensor; default = nil)
- opts.legend : 包含图例名字的table
- opts.textlabels : 每一个点的文本标签 (list: default = None)
- opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
- opts.traceopts : 将跟踪名称或索引映射到plot.ly为追踪接受的附加选项的字典. 比如 traceopts = {'plotly': {'myTrace': {'mode': 'markers'}}}.
- opts.webgl : 使用WebGL绘图(布尔值;default= false。如果一个图包含太多的点,它会更快。要谨慎使用,因为浏览器不会在一个页面上允许多个WebGL上下文。
options.markercolor 是一个包含整数值的Tensor。Tensor的形状可以是 N 或 N x 3 或 K 或 K x 3.
- Tensor of size N: 表示每个点的单通道颜色强度。 0 = black, 255 = red
- Tensor of size N x 3: 用三通道表示每个点的颜色。 0,0,0 = black, 255,255,255 = white
- Tensor of size K and K x 3: 为每个类别指定颜色,不是为每个点指定颜色。
举例:
1》
- # scatter plots
- Y = np.random.rand(100)
- old_scatter = viz.scatter(
- X=np.random.rand(100, 2),
- Y=(Y[Y > 0] + 1.5).astype(int),
- opts=dict(
- legend=['Didnt', 'Update'],
- xtickmin=-50,
- xtickmax=50,
- xtickstep=0.5,
- ytickmin=-50,
- ytickmax=50,
- ytickstep=0.5,
- markersymbol='cross-thin-open',
- ),
- )
- viz.update_window_opts(
- win=old_scatter,
- opts=dict(
- legend=['Apples', 'Pears'],
- xtickmin=0,
- xtickmax=1,
- xtickstep=0.5,
- ytickmin=0,
- ytickmax=1,
- ytickstep=0.5,
- markersymbol='cross-thin-open',
- ),
- )
图示:
2》3D版的:
- # 3d scatterplot with custom labels and ranges
- viz.scatter(
- X=np.random.rand(100, 3),
- Y=(Y + 1.5).astype(int),
- opts=dict(
- legend=['Men', 'Women'],
- markersize=5,
- xtickmin=0,
- xtickmax=2,
- xlabel='Arbitrary',
- xtickvals=[0, 0.75, 1.6, 2],
- ytickmin=0,
- ytickmax=2,
- ytickstep=0.5,
- ztickmin=0,
- ztickmax=1,
- ztickstep=0.5,
- )
- )
图示:
3》带有自定义强度的2D散点图(红色通道)
- # 2D scatterplot with custom intensities (red channel)
- viz.scatter(
- X=np.random.rand(255, 2),
- Y=(np.random.rand(255) + 1.5).astype(int),
- opts=dict(
- markersize=10,
- markercolor=np.random.randint(0, 255, (2, 3,)),
- ),
- )
图示:
4》2D散点图,每个标签自定义颜色:
- # 2D scatter plot with custom colors per label:
- viz.scatter(
- X=np.random.rand(255, 2),
- Y=(np.random.randn(255) > 0) + 1,
- opts=dict(
- markersize=10,
- markercolor=np.floor(np.random.random((2, 3)) * 255),
- ),
- )
图示:
5》添加新的追踪
- win = viz.scatter(
- X=np.random.rand(255, 2),
- opts=dict(
- markersize=10,
- markercolor=np.random.randint(0, 255, (255, 3,)),
- ),
- )
- #断言该窗口是否存在
- assert viz.win_exists(win), 'Created window marked as not existing'
- # 添加新的追踪到散点图中
- viz.scatter(
- X=np.random.rand(255),
- Y=np.random.rand(255),
- win=win,
- name='new_trace',
- update='new'
- )
图示:
6》带着文本标签的散点图
- # 2D scatter plot with text labels:
- viz.scatter(
- X=np.random.rand(10, 2),
- opts=dict(
- textlabels=['Label %d' % (i + 1) for i in range(10)]
- )
- )
- viz.scatter(
- X=np.random.rand(10, 2),
- Y=[1] * 5 + [2] * 3 + [3] * 2,
- opts=dict(
- legend=['A', 'B', 'C'],
- textlabels=['Label %d' % (i + 1) for i in range(10)]
- )
- )
图示:
7》更新
1〉一开始的底图
- colors = np.random.randint(0, 255, (2, 3,))
- win = viz.scatter(
- X=np.random.rand(255, 2),
- Y=(np.random.rand(255) + 1.5).astype(int),
- opts=dict(
- markersize=10,
- markercolor=colors,
- legend=['1', '2']
- ),
- )
图是:
2〉append
- viz.scatter(
- X=np.random.rand(255),
- Y=np.random.rand(255),
- opts=dict(
- markersize=10,
- markercolor=colors[0].reshape(-1, 3),
- ),
- name='1',
- update='append',
- win=win)
图为:
3〉append
- viz.scatter(
- X=np.random.rand(255, 2),
- Y=(np.random.rand(255) + 1.5).astype(int),
- opts=dict(
- markersize=10,
- markercolor=colors,
- ),
- update='append',
- win=win)
图为:
2>vis.line
这个函数画了一条线。它接受一个N或NxM张量Y作为输入,它指定连接N个点的M条线的值。它还接受一个可选的X张量,指定相应的X轴值;X可以是一个N张量(在这种情况下,所有的线都有相同的X轴值),或者和Y大小相同。
update可用于有效地更新现有图的数据。使用'append'附加数据,'replace'使用新数据,或'remove'删除按名称指定的跟踪。如果更新单个跟踪,请使用name指定要更新的跟踪的名称。忽略所有NaN的更新数据(可用于屏蔽更新)。
下面是支持的opts:
opts.fillarea
: 填满线下区域(boolean
)opts.markers
: 显示标记 (boolean
; default =false
)opts.markersymbol
: 标记符号(string
; default ='dot'
)opts.markersize
:标记大小(number
; default ='10'
)opts.linecolor
:线颜色 (np.array
; default = None)opts.dash
: 每一行的破折号类型 (np.array
; default = 'solid'), 实线、破折号、虚线或破折号中的一个,其大小应与所画线的数目相匹配opts.legend
: 包含图例名称的表- opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
- opts.traceopts : 将跟踪名称或索引映射到plot.ly为追踪接受的附加选项的字典. 比如 traceopts = {'plotly': {'myTrace': {'mode': 'markers'}}}.
- opts.webgl : 使用WebGL绘图(布尔值;default= false。如果一个图包含太多的点,它会更快。要谨慎使用,因为浏览器不会在一个页面上允许多个WebGL上下文。
1》
- # line plots
- viz.line(Y=np.random.rand(10), opts=dict(showlegend=True))
- Y = np.linspace(-5, 5, 100)
- viz.line(
- Y=np.column_stack((Y * Y, np.sqrt(Y + 5))),
- X=np.column_stack((Y, Y)),
- opts=dict(markers=False),
- )
图示:
2》
- # line using WebGL
- webgl_num_points = 200000
- webgl_x = np.linspace(-1, 0, webgl_num_points)
- webgl_y = webgl_x**3
- viz.line(X=webgl_x, Y=webgl_y,
- opts=dict(title='{} points using WebGL'.format(webgl_num_points), webgl=True),
- win="WebGL demo")
图示:
3》更新
- # line updates
- win = viz.line(
- X=np.column_stack((np.arange(0, 10), np.arange(0, 10))),
- Y=np.column_stack((np.linspace(5, 10, 10),
- np.linspace(5, 10, 10) + 5)),
- )
图为:
append:
- viz.line(
- X=np.column_stack((np.arange(10, 20), np.arange(10, 20))),
- Y=np.column_stack((np.linspace(5, 10, 10),
- np.linspace(5, 10, 10) + 5)),
- win=win,
- update='append'
- )
图为:
append:
- viz.line(
- X=np.arange(21, 30),
- Y=np.arange(1, 10),
- win=win,
- name='2',
- update='append'
- )
图示:
append:
- viz.line(
- X=np.arange(1, 10),
- Y=np.arange(11, 20),
- win=win,
- name='delete this',
- update='append'
- )
图为:
insert:
- viz.line(
- X=np.arange(1, 10),
- Y=np.arange(11, 20),
- win=win,
- name='4',
- update='insert'
- )
图为:
remove:
- viz.line(X=None, Y=None, win=win, name='delete this', update='remove')
图又会回到上上面一个:
这个更改的是之前使用WebGL的那个图:
- viz.line(
- X=webgl_x+1.,
- Y=(webgl_x+1.)**3,
- win="WebGL demo",
- update='append',
- opts=dict(title='{} points using WebGL'.format(webgl_num_points*2), webgl=True)
- )
图变为:
4》实线、虚线等不同线的实现
- win = viz.line(
- X=np.column_stack((
- np.arange(0, 10),
- np.arange(0, 10),
- np.arange(0, 10),
- )),
- Y=np.column_stack((
- np.linspace(5, 10, 10),
- np.linspace(5, 10, 10) + 5,
- np.linspace(5, 10, 10) + 10,
- )),
- opts={
- 'dash': np.array(['solid', 'dash', 'dashdot']),
- 'linecolor': np.array([
- [0, 191, 255],
- [0, 191, 255],
- [255, 0, 0],
- ]),
- 'title': 'Different line dash types'
- }
- )
- viz.line(
- X=np.arange(0, 10),
- Y=np.linspace(5, 10, 10) + 15,
- win=win,
- name='4',
- update='insert',
- opts={
- 'linecolor': np.array([
- [255, 0, 0],
- ]),
- 'dash': np.array(['dot']),
- }
- )
图示:
5》堆叠区域
- Y = np.linspace(0, 4, 200)
- win = viz.line(
- Y=np.column_stack((np.sqrt(Y), np.sqrt(Y) + 2)),
- X=np.column_stack((Y, Y)),
- opts=dict(
- fillarea=True,
- showlegend=False,
- width=800,
- height=800,
- xlabel='Time',
- ylabel='Volume',
- ytype='log',
- title='Stacked area plot',
- marginleft=30,
- marginright=30,
- marginbottom=80,
- margintop=30,
- ),
- )
图示:
更新参数:
- # 确保堆叠区域不过大
- viz.update_window_opts(
- win=win,
- opts=dict(
- width=300,
- height=300,
- ),
- )
图变为:
6)pytorch tensor
- # PyTorch tensor
- try:
- import torch
- viz.line(Y=torch.Tensor([[., .], [., .]]))
- except ImportError:
- print('Skipped PyTorch example')
图示:
3>vis.stem
这个函数绘制一个根茎图。它接受一个N或NxM张量X作为输入,它指定M时间序列中N个点的值。还可以指定一个包含时间戳的可选N或NxM张量Y;如果Y是一个N张量,那么所有M个时间序列都假设有相同的时间戳。
下面是支持的opts:
opts.colormap
: 色图 (string
; default ='Viridis'
)opts.legend
: 包含图例名称的表- opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # stemplot
- Y = np.linspace(0, 2 * math.pi, 70)
- X = np.column_stack((np.sin(Y), np.cos(Y)))
- viz.stem(
- X=X,
- Y=Y,
- opts=dict(legend=['Sine', 'Cosine'])
- )
图示:
4>vis.heatmap
此函数绘制热点图。它接受一个NxM张量X作为输入,它指定了热图中每个位置的值。
下面是支持的opts:
opts.colormap
: 色图 (string
; default ='Viridis'
)opts.xmin
: 修剪的最小值 (number
; default =X:min()
)opts.xmax
: 修剪的最大值(number
; default =X:max()
)opts.columnnames
:包含
x-axis 标签的表opts.rownames
:包含
y-axis 标签的表opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # heatmap
- viz.heatmap(
- X=np.outer(np.arange(1, 6), np.arange(1, 11)),
- opts=dict(
- columnnames=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
- rownames=['y1', 'y2', 'y3', 'y4', 'y5'],
- colormap='Electric',
- )
- )
图示:
5>vis.bar
此函数绘制规则的、堆叠的或分组的条形图。它接受一个N或NxM张量X作为输入,它指定了每个条的高度。如果X包含M列,则对每一行对应的值进行堆叠或分组(取决于opts.stacked的选择方式)。除了X,还可以指定一个(可选的)N张量Y,它包含相应的X轴值。
以下是目前支持的特定plot的选项:
opts.rownames
:包含
x-axis 标签的表opts.stacked
:在X中堆叠多个列
opts.legend
: 包含图例名称的表opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
1》
- # bar plots
- viz.bar(X=np.random.rand(20))
图示:
2》
- viz.bar(
- X=np.abs(np.random.rand(5, 3)),
- opts=dict(
- stacked=True,
- legend=['Facebook', 'Google', 'Twitter'],
- rownames=['2012', '2013', '2014', '2015', '2016']
- )
- )
图示:
3》
- viz.bar(
- X=np.random.rand(20, 3),
- opts=dict(
- stacked=False,
- legend=['The Netherlands', 'France', 'United States']
- )
- )
图示:
6>vis.histogram
这个函数绘制指定数据的直方图。它接受一个N张量X作为输入,它指定了用来构造直方图的数据。
以下是目前支持的特定plot的选项:
opts.numbins
: bins数量 (number
; default = 30)opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # histogram
- viz.histogram(X=np.random.rand(10000), opts=dict(numbins=20))
图示:
7> vis.boxplot
此函数绘制指定数据的箱形图。它接受一个N或一个NxM张量X作为输入,该张量X指定了N个数据值,用来构造M个箱形图。
以下是目前支持的特定plot的选项:
opts.legend
: 在X中每一列的标签opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # boxplot
- X = np.random.rand(100, 2)
- X[:, 1] += 2
- viz.boxplot(
- X=X,
- opts=dict(legend=['Men', 'Women'])
- )
图示:
8>vis.surf
这个函数绘制一个曲面图。它接受一个NxM张量X作为输入,该张量X指定了曲面图中每个位置的值。
下面是支持的opts:
opts.colormap
: 色图 (string
; default ='Viridis'
)opts.xmin
: 修剪的最小值 (number
; default =X:min()
)opts.xmax
: 修剪的最大值(number
; default =X:max()
)opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # surface
- viz.surf(X=X, opts=dict(colormap='Hot'))
图示:
9>vis.contour
这个函数绘制等高线。它接受一个NxM张量X作为输入,该张量X指定等高线图中每个位置的值。
下面是支持的opts:
opts.colormap
: 色图 (string
; default ='Viridis'
)opts.xmin
: 修剪的最小值 (number
; default =X:min()
)opts.xmax
: 修剪的最大值(number
; default =X:max()
)opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # contour
- x = np.tile(np.arange(1, 101), (100, 1))
- y = x.transpose()
- X = np.exp((((x - 50) ** 2) + ((y - 50) ** 2)) / -(20.0 ** 2))
- viz.contour(X=X, opts=dict(colormap='Viridis'))
图示:
10>vis.quiver
该函数绘制一个抖动图,其中箭头的方向和长度由NxM张量X和y决定。可以提供两个可选的NxM张量gridX和gridY,指定箭头的偏移量;默认情况下,箭头将在常规网格上执行。
下面是支持的opts:
opts.normalize
: 最长箭头长度 (number
)opts.arrowheads
: 显示箭头 (boolean
; default =true
)opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # quiver plot
- X = np.arange(0, 2.1, .2)
- Y = np.arange(0, 2.1, .2)
- X = np.broadcast_to(np.expand_dims(X, axis=1), (len(X), len(X)))
- Y = np.broadcast_to(np.expand_dims(Y, axis=0), (len(Y), len(Y)))
- U = np.multiply(np.cos(X), Y)
- V = np.multiply(np.sin(X), Y)
- viz.quiver(
- X=U,
- Y=V,
- opts=dict(normalize=0.9),
- )
图示:
11>vis.mesh
这个函数从一组在Nx2或Nx3矩阵X中定义的顶点和在可选的Mx2或Mx3矩阵Y中定义的多边形中绘制网格图。
下面是支持的opts:
opts.color
: 颜色 (string
)opts.opacity
: 多边形的不透明度 (number
between 0 and 1)opts.layoutopts : 图形后端为布局接受的任何附加选项的字典. 比如 layoutopts = {'plotly': {'legend': {'x':0, 'y':0}}}.
举例:
- # mesh plot
- x = [0, 0, 1, 1, 0, 0, 1, 1]
- y = [0, 1, 1, 0, 0, 1, 1, 0]
- z = [0, 0, 0, 0, 1, 1, 1, 1]
- X = np.c_[x, y, z]
- i = [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2]
- j = [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3]
- k = [0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6]
- Y = np.c_[i, j, k]
- viz.mesh(X=X, Y=Y, opts=dict(opacity=0.5))
图为:
12>vis.pie饼图
举例:
- # pie chart
- X = np.asarray([19, 26, 55])
- viz.pie(
- X=X,
- opts=dict(legend=['Residential', 'Non-Residential', 'Utility'])
- )
图示:
pytorch visdom可视化工具学习—1—详细使用-2-plotting绘图的更多相关文章
- pytorch visdom可视化工具学习—1—详细使用-1—基本使用函数
使用教程,参考: https://github.com/facebookresearch/visdom https://www.pytorchtutorial.com/using-visdom-for ...
- pytorch visdom可视化工具学习—1—详细使用-3-Generic Plots和Others
4)Generic Plots 注意,服务器API遵循数据和布局对象的规则,这样您就可以生成自己的任意Plotly可视化: # Arbitrary visdom content trace = dic ...
- pytorch visdom可视化工具学习—1—安装和使用
1.安装 安装命令: (deeplearning) userdeMBP:~ user$ pip install visdomCollecting visdom Downloading https:/ ...
- pytorch visdom可视化工具学习—3-命令行操作使用经验
在使用过程中一直以为要在哪个指定的environment下(即参数env)绘制内容,就必须在使用时声明 比如如果不声明,默认的就是在'main'环境下,端口为8097: viz = visdom.Vi ...
- Pytorch Visdom可视化工具
2018-12-04 14:05:49 Visdom是Facebook专门为PyTorch开发的一款可视化工具,其开源于2017年3月.Visdom十分轻量级,但却支持非常丰富的功能,能胜任大多数的科 ...
- 深度学习框架PyTorch一书的学习-第五章-常用工具模块
https://github.com/chenyuntc/pytorch-book/blob/v1.0/chapter5-常用工具/chapter5.ipynb 希望大家直接到上面的网址去查看代码,下 ...
- [深度学习] pytorch学习笔记(3)(visdom可视化、正则化、动量、学习率衰减、BN)
一.visdom可视化工具 安装:pip install visdom 启动:命令行直接运行visdom 打开WEB:在浏览器使用http://localhost:8097打开visdom界面 二.使 ...
- 深度学习框架PyTorch一书的学习-第六章-实战指南
参考:https://github.com/chenyuntc/pytorch-book/tree/v1.0/chapter6-实战指南 希望大家直接到上面的网址去查看代码,下面是本人的笔记 将上面地 ...
- Visdom可视化
Visdom是基于Pytorch的可视化工具 安装方式: pip install visdom 因为Visdom本质上是一个Web服务器,把数据渲染到网页上,因此首先需要运行这个 服务器,如下: py ...
随机推荐
- idea护眼色设置
idea右侧编辑区设置护眼色
- idea输入法不跟随解决办法
最近使用idea开发项目,遇到输入法不跟随的问题,自己动手解决了下 idea输入法不跟随解决办法: 1):系统:windows10 版本:idea2017.2 解决办法:使用QQ输入法 2):系统:w ...
- 【mysql】2003-Can't connect to MySQL server (10060)
使用navicat或者其他数据库管理工具连接mysql时出现2003-Can’t connect to MySQL server (10060)错误 可能造成出现的原因: 1.网络不通畅 2.mysq ...
- JAX-WS Web Service小试牛刀
1.使用Eclipse新建Java工程JavaDemo 2.新建包com.kira.ws 3.在包com.kira.ws新建类Hello,代码如下 package com.kira.ws; impor ...
- vue-cli创建的项目的目录结构及说明
转自:http://blog.csdn.net/qq_34543438/article/details/72868546?locationNum=3&fps=1 一. ├── build ...
- Java 导出 Excel 列号数字与字母互相转换工具
package test; /** * Deal with Excel column indexToStr and strToIndex * @author * @version 2015-7-8 * ...
- JavaScript易错知识点整理[转]
前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...
- JS与CSS阻止元素被选中及清除选中的方法总结
有时候,我们希望阻止用户选中我们指定区域的文字或内容. 举个栗子,有时候用户在一个区域执行频繁的点击操作,一不小心傲娇地点多了,就会选中当前区域的内容. 再举个栗子,制作轮播组件的时候,点击下一页,若 ...
- touch.js 拖动、缩放、旋转 (鼠标手势)
可以实现手势操作:拖动.缩放.旋转.封装好的脚本方法是这样的: var cat = window.cat || {}; cat.touchjs = { left: 0, top: 0, scaleVa ...
- 一年过去了,25万月薪的AI工程师还存在吗?
导读:2017 年的时候,AI 前线进行了一场有关人工智能领域薪资差异的专题策划,这篇名为<25 万年薪的你与 25 万月薪的他,猎头来谈你们之间的差别>的文章引起了读者们的热烈讨论.一年 ...