【前言】对于气象专业的小学生来说,风场是预报重要的参考数据,我们所知的风羽有四种:短线代表风速2m/s,长线代表风速4m/s,空心三角代表风速20m/s,实心三角代表风速50m/s。而matplotlib的风羽只有短线、长线、三角三种,而这里的三角不分空心实心,但是可通过改变风羽颜色为白色使三角变为空心形状,虽然这三种可以自定义各自代表的风速,但是仍与我们的使用习惯不符,即使把三角设成20m/s,原本一个实心三角就能表示的50m/s的风在matplotlib中需要两个三角外加两条长线一条短线。为了迎合预报员的需求,我在研究了matplotlib的风场函数barbs()的源代码quiver.py文件后,对quiver.py做了适当的调整,使得matplotlib也有了空心三角和实心三角之分。

一、函数barbs的使用

  1. barb(X, Y, U, V,, **kw)

X:风场数据X坐标

Y:风场数据Y坐标

U:风的水平方向分量

V:风的垂直方向分量

  1. '''
  2. Demonstration of wind barb plots
  3. '''
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. x = np.linspace(-5, 5, 5)
  7. X, Y = np.meshgrid(x, x)
  8. U, V = 12*X, 12*Y
  9. data = [(-1.5, .5, -6, -6),(1, -1, -46, 46),(-3, -1, 11, -11),(1, 1.5, 80, 80),(0.5, 0.25, 25, 15),(-1.5, -0.5, -5, 40)]
  10. data = np.array(data, dtype=[('x', np.float32), ('y', np.float32), ('u', np.float32), ('v', np.float32)])
  11. # Default parameters, uniform grid
  12. ax = plt.subplot(2, 2, 1)
  13. ax.barbs(X, Y, U, V)
  14. # Arbitrary set of vectors, make them longer and change the pivot point
  15. #(point around which they're rotated) to be the middle
  16. ax = plt.subplot(2, 2, 2)
  17. ax.barbs(data['x'], data['y'], data['u'], data['v'], length=8, pivot='middle')
  18. # Showing colormapping with uniform grid. Fill the circle for an empty barb,
  19. # don't round the values, and change some of the size parameters
  20. ax = plt.subplot(2, 2, 3)
  21. ax.barbs(X, Y, U, V, np.sqrt(U*U + V*V), fill_empty=True, rounding=False,sizes=dict(emptybarb=0.25, spacing=0.2, height=0.3))
  22. # Change colors as well as the increments for parts of the barbs
  23. ax = plt.subplot(2, 2, 4)
  24. ax.barbs(data['x'], data['y'], data['u'], data['v'], flagcolor='r',barbcolor=['b', 'g'], barb_increments=dict(half=10, full=20, flag=100),flip_barb=True)
  25. plt.show()

二、源代码解读

1.class Barbs()

  1. class Barbs(mcollections.PolyCollection):
  2. @docstring.interpd
  3. def __init__(self, ax, *args, **kw):
  4. '...'
  5. def _find_tails(self, mag, rounding=True, half=5, full=10, flag=50):
  6. '...'
  7. def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length,pivot, sizes, fill_empty, flip):
  8. '...'
  9. def set_UVC(self, U, V, C=None):
  10. '...'
  11. def set_offsets(self, xy):
  12. '...'
  • 通过读源代码可知类Barbs有五个方法分别为__init___find_tails_make_barbsset_UVCset_offsets

2.__init__

  1. @docstring.interpd
  2. def __init__(self, ax, *args, **kw):
  3. """
  4. The constructor takes one required argument, an Axes
  5. instance, followed by the args and kwargs described
  6. by the following pylab interface documentation:
  7. %(barbs_doc)s
  8. """
  9. self._pivot = kw.pop('pivot', 'tip')
  10. self._length = kw.pop('length', 7)
  11. barbcolor = kw.pop('barbcolor', None)
  12. flagcolor = kw.pop('flagcolor', None)
  13. self.sizes = kw.pop('sizes', dict())
  14. self.fill_empty = kw.pop('fill_empty', False)
  15. self.barb_increments = kw.pop('barb_increments', dict())
  16. self.rounding = kw.pop('rounding', True)
  17. self.flip = kw.pop('flip_barb', False)
  18. transform = kw.pop('transform', ax.transData)
  19. # Flagcolor and and barbcolor provide convenience parameters for
  20. # setting the facecolor and edgecolor, respectively, of the barb
  21. # polygon. We also work here to make the flag the same color as the
  22. # rest of the barb by default
  23. if None in (barbcolor, flagcolor):
  24. kw['edgecolors'] = 'face'
  25. if flagcolor:
  26. kw['facecolors'] = flagcolor
  27. elif barbcolor:
  28. kw['facecolors'] = barbcolor
  29. else:
  30. # Set to facecolor passed in or default to black
  31. kw.setdefault('facecolors', 'k')
  32. else:
  33. kw['edgecolors'] = barbcolor
  34. kw['facecolors'] = flagcolor
  35. # Parse out the data arrays from the various configurations supported
  36. x, y, u, v, c = _parse_args(*args)
  37. self.x = x
  38. self.y = y
  39. xy = np.hstack((x[:, np.newaxis], y[:, np.newaxis]))
  40. # Make a collection
  41. barb_size = self._length ** 2 / 4 # Empirically determined
  42. mcollections.PolyCollection.__init__(self, [], (barb_size,),
  43. offsets=xy,
  44. transOffset=transform, **kw)
  45. self.set_transform(transforms.IdentityTransform())
  46. self.set_UVC(u, v, c)
  • __init__()方法为初始化方法,此方法中flagcolorbarbcolor为设置风羽颜色的关键字,中间的说明文字提示颜色设置是针对所有的风羽的,所以通过颜色设置达不到风羽中既有空心白色三角又有实心黑色三角。初始化方法中在对一些参数进行了初始化赋值后执行了set_UVC()方法,所以我们顺着这个set_UVC()方法往下继续读。

3.set_UVC()

  1. def set_UVC(self, U, V, C=None):
  2. self.u = ma.masked_invalid(U, copy=False).ravel()
  3. self.v = ma.masked_invalid(V, copy=False).ravel()
  4. if C is not None:
  5. c = ma.masked_invalid(C, copy=False).ravel()
  6. x, y, u, v, c = delete_masked_points(self.x.ravel(),
  7. self.y.ravel(),
  8. self.u, self.v, c)
  9. else:
  10. x, y, u, v = delete_masked_points(self.x.ravel(), self.y.ravel(),
  11. self.u, self.v)
  12. magnitude = np.hypot(u, v)
  13. flags, emptyflags,barbs, halves, empty = self._find_tails(magnitude,
  14. self.rounding,
  15. **self.barb_increments)
  16. # Get the vertices for each of the barbs
  17. plot_barbs = self._make_barbs(u, v, flags, emptyflags,barbs, halves, empty,
  18. self._length, self._pivot, self.sizes,
  19. self.fill_empty, self.flip)
  20. self.set_verts(plot_barbs)
  21. # Set the color array
  22. if C is not None:
  23. self.set_array(c)
  24. # Update the offsets in case the masked data changed
  25. xy = np.hstack((x[:, np.newaxis], y[:, np.newaxis]))
  26. self._offsets = xy
  27. self.stale = True
  • 在此方法中,首先进行了变量的命名赋值,然后依次执行了方法_find_tails_make_barbs_make_barbs的输入为_find_tails的输出,_find_tails的输入中有一个为magnitude = np.hypot(u, v)np.hypot()为勾股定理方法,因此可知magnitude为风速。

4._find_tails

  1. def _find_tails(self, mag, rounding=True, half=5, full=10, flag=50):
  2. '''
  3. Find how many of each of the tail pieces is necessary. Flag
  4. specifies the increment for a flag, barb for a full barb, and half for
  5. half a barb. Mag should be the magnitude of a vector (i.e., >= 0).
  6. This returns a tuple of:
  7. (*number of flags*, *number of barbs*, *half_flag*, *empty_flag*)
  8. *half_flag* is a boolean whether half of a barb is needed,
  9. since there should only ever be one half on a given
  10. barb. *empty_flag* flag is an array of flags to easily tell if
  11. a barb is empty (too low to plot any barbs/flags.
  12. '''
  13. # If rounding, round to the nearest multiple of half, the smallest
  14. # increment
  15. if rounding:
  16. mag = half * (mag / half + 0.5).astype(np.int)
  17. num_flags = np.floor(mag / flag).astype(np.int)
  18. mag = np.mod(mag, flag)
  19. num_barb = np.floor(mag / full).astype(np.int)
  20. mag = np.mod(mag, full)
  21. half_flag = mag >= half
  22. empty_flag = ~(half_flag | (num_flags > 0) | (num_emptyflags > 0) |(num_barb > 0))
  23. return num_flags,num_barb, half_flag, empty_flag
  • 通过读此方法的说明文档可知,此方法作用为根据输入的风速、设置的短线长线三角的数值计算并返回三角、长线、短线的个数以及有没有无风的情况。

5._make_barbs

  1. def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length,
  2. pivot, sizes, fill_empty, flip):
  3. '''
  4. This function actually creates the wind barbs. *u* and *v*
  5. are components of the vector in the *x* and *y* directions,
  6. respectively.
  7. *nflags*, *nbarbs*, and *half_barb*, empty_flag* are,
  8. *respectively, the number of flags, number of barbs, flag for
  9. *half a barb, and flag for empty barb, ostensibly obtained
  10. *from :meth:`_find_tails`.
  11. *length* is the length of the barb staff in points.
  12. *pivot* specifies the point on the barb around which the
  13. entire barb should be rotated. Right now, valid options are
  14. 'head' and 'middle'.
  15. *sizes* is a dictionary of coefficients specifying the ratio
  16. of a given feature to the length of the barb. These features
  17. include:
  18. - *spacing*: space between features (flags, full/half
  19. barbs)
  20. - *height*: distance from shaft of top of a flag or full
  21. barb
  22. - *width* - width of a flag, twice the width of a full barb
  23. - *emptybarb* - radius of the circle used for low
  24. magnitudes
  25. *fill_empty* specifies whether the circle representing an
  26. empty barb should be filled or not (this changes the drawing
  27. of the polygon).
  28. *flip* is a flag indicating whether the features should be flipped to
  29. the other side of the barb (useful for winds in the southern
  30. hemisphere.
  31. This function returns list of arrays of vertices, defining a polygon
  32. for each of the wind barbs. These polygons have been rotated to
  33. properly align with the vector direction.
  34. '''
  35. # These control the spacing and size of barb elements relative to the
  36. # length of the shaft
  37. spacing = length * sizes.get('spacing', 0.125)
  38. full_height = length * sizes.get('height', 0.4)
  39. full_width = length * sizes.get('width', 0.25)
  40. empty_rad = length * sizes.get('emptybarb', 0.15)
  41. # Controls y point where to pivot the barb.
  42. pivot_points = dict(tip=0.0, middle=-length / 2.)
  43. # Check for flip
  44. if flip:
  45. full_height = -full_height
  46. endx = 0.0
  47. endy = pivot_points[pivot.lower()]
  48. # Get the appropriate angle for the vector components. The offset is
  49. # due to the way the barb is initially drawn, going down the y-axis.
  50. # This makes sense in a meteorological mode of thinking since there 0
  51. # degrees corresponds to north (the y-axis traditionally)
  52. angles = -(ma.arctan2(v, u) + np.pi / 2)
  53. # Used for low magnitude. We just get the vertices, so if we make it
  54. # out here, it can be reused. The center set here should put the
  55. # center of the circle at the location(offset), rather than at the
  56. # same point as the barb pivot; this seems more sensible.
  57. circ = CirclePolygon((0, 0), radius=empty_rad).get_verts()
  58. if fill_empty:
  59. empty_barb = circ
  60. else:
  61. # If we don't want the empty one filled, we make a degenerate
  62. # polygon that wraps back over itself
  63. empty_barb = np.concatenate((circ, circ[::-1]))
  64. barb_list = []
  65. for index, angle in np.ndenumerate(angles):
  66. # If the vector magnitude is too weak to draw anything, plot an
  67. # empty circle instead
  68. if empty_flag[index]:
  69. # We can skip the transform since the circle has no preferred
  70. # orientation
  71. barb_list.append(empty_barb)
  72. continue
  73. poly_verts = [(endx, endy)]
  74. offset = length
  75. # Add vertices for each flag
  76. for i in range(nflags[index]):
  77. # The spacing that works for the barbs is a little to much for
  78. # the flags, but this only occurs when we have more than 1
  79. # flag.
  80. if offset != length:
  81. offset += spacing / 2.
  82. poly_verts.extend(
  83. [[endx, endy + offset],
  84. [endx + full_height, endy - full_width / 2 + offset],
  85. [endx, endy - full_width + offset]])
  86. offset -= full_width + spacing
  87. # Add vertices for each barb. These really are lines, but works
  88. # great adding 3 vertices that basically pull the polygon out and
  89. # back down the line
  90. for i in range(nbarbs[index]):
  91. poly_verts.extend(
  92. [(endx, endy + offset),
  93. (endx + full_height, endy + offset + full_width / 2),
  94. (endx, endy + offset)])
  95. offset -= spacing
  96. # Add the vertices for half a barb, if needed
  97. if half_barb[index]:
  98. # If the half barb is the first on the staff, traditionally it
  99. # is offset from the end to make it easy to distinguish from a
  100. # barb with a full one
  101. if offset == length:
  102. poly_verts.append((endx, endy + offset))
  103. offset -= 1.5 * spacing
  104. poly_verts.extend(
  105. [(endx, endy + offset),
  106. (endx + full_height / 2, endy + offset + full_width / 4),
  107. (endx, endy + offset)])
  108. # Rotate the barb according the angle. Making the barb first and
  109. # then rotating it made the math for drawing the barb really easy.
  110. # Also, the transform framework makes doing the rotation simple.
  111. poly_verts = transforms.Affine2D().rotate(-angle).transform(
  112. poly_verts)
  113. barb_list.append(poly_verts)
  114. return barb_list
  • 通过读此方法的说明文档可知,此方法作用为根据输入的风数据以及短线长线三角的个数绘制风羽风向杆。
  • 绘制过程为:判断地图坐标点是不是无风,如果无风就绘制一个空心圆圈代表。如果有风就开始按照三角、长线、短线的顺序绘制。
  • 绘制方法为:
  1. 创建一个用于存储关键点坐标的列表poly_verts
  2. 计算关键点坐标
  3. 通过transform方法将关键点坐标列表中的各个关键点依次用黑线连接起来,最终将风羽风向杆绘制出来
  • 此方法的几个关键变量:
  1. spacing:风羽上短线长线以及三角间的距离
  2. full_height:三角的高度
  3. full_width :三角的宽度
  4. endx :风羽绘制的起始点x坐标
  5. endy:风羽绘制的起始点y坐标
  6. angles:风向杆角度
  7. poly_verts :绘制风羽风向杆的关键点列表
  8. offset:绘制完一个三角或线后下一个三角或线的关键起始坐标
  1. poly_verts = [(endx, endy)]
  2. offset = length
  3. # Add vertices for each flag
  4. for i in range(nflags[index]):
  5. # The spacing that works for the barbs is a little to much for
  6. # the flags, but this only occurs when we have more than 1
  7. # flag.
  8. if offset != length:
  9. offset += spacing / 2.
  10. poly_verts.extend(
  11. [[endx, endy + offset],
  12. [endx + full_height, endy - full_width / 2 + offset],
  13. [endx, endy - full_width + offset]])
  14. offset -= full_width + spacing
  • 这一段是绘制风羽的主要代码,利用图片的形式说明

三、绘制空心实心三角

在了解了风羽的绘制过程后,发现可以通过增加关键点直接绘制实心三角,通过原绘制方法绘制空心三角。

1.实心三角绘制

  • 实心三角绘制代码
  1. # Add vertices for each flag
  2. for i in range(nflags[index]):
  3. # The spacing that works for the barbs is a little to much for
  4. # the flags, but this only occurs when we have more than 1
  5. # flag.
  6. if offset != length:
  7. offset += spacing / 2.
  8. poly_verts.extend(
  9. [[endx, endy + offset],
  10. [endx + full_height/4, endy - full_width / 8 + offset],
  11. [endx, endy - full_width / 8 + offset],
  12. [endx + full_height/4, endy - full_width / 8 + offset],
  13. [endx + full_height/2, endy - full_width / 4 + offset],
  14. [endx, endy - full_width / 4 + offset],
  15. [endx + full_height/2, endy - full_width / 4 + offset],
  16. [endx + 3*full_height/4, endy - 3*full_width / 8 + offset],
  17. [endx, endy - 3*full_width / 8 + offset],
  18. [endx + 3*full_height/4, endy - 3*full_width / 8 + offset],
  19. [endx + full_height, endy - full_width / 2 + offset],
  20. [endx,endy-full_width/2+offset],
  21. [endx + full_height, endy - full_width / 2 + offset],
  22. [endx + 3*full_height/4, endy - 5*full_width / 8 + offset],
  23. [endx, endy - 5*full_width / 8 + offset],
  24. [endx + 3*full_height/4, endy - 5*full_width / 8 + offset],
  25. [endx + full_height/2, endy - 3*full_width / 4 + offset],
  26. [endx, endy - 3*full_width / 4 + offset],
  27. [endx + full_height/2, endy - 3*full_width / 4 + offset],
  28. [endx + full_height/4, endy - 7*full_width / 8 + offset],
  29. [endx, endy - 7*full_width / 8 + offset],
  30. [endx + full_height/4, endy - 7*full_width / 8 + offset],
  31. [endx, endy - full_width + offset]])
  32. offset -= full_width + spacing
  • 实心三角绘制示意图

  • 方法参数中加入nfullflags

  1. def _make_barbs(self, u, v, nfullflags, nflags,nbarbs, half_barb, empty_flag, length,pivot, sizes, fill_empty, flip):
  2. '...'

2.实心三角个数计算

  1. def _find_tails(self, mag, rounding=True, half=2, full=4, flag=20,fullflag=50):
  2. '''
  3. Find how many of each of the tail pieces is necessary. Flag
  4. specifies the increment for a flag, barb for a full barb, and half for
  5. half a barb. Mag should be the magnitude of a vector (i.e., >= 0).
  6. This returns a tuple of:
  7. (*number of flags*, *number of barbs*, *half_flag*, *empty_flag*)
  8. *half_flag* is a boolean whether half of a barb is needed,
  9. since there should only ever be one half on a given
  10. barb. *empty_flag* flag is an array of flags to easily tell if
  11. a barb is empty (too low to plot any barbs/flags.
  12. '''
  13. # If rounding, round to the nearest multiple of half, the smallest
  14. # increment
  15. if rounding:
  16. mag = half * (mag / half + 0.5).astype(np.int)
  17. num_fullflags = np.floor(mag / fullflag).astype(np.int)
  18. mag = np.mod(mag, fullflag)
  19. num_flags = np.floor(mag / flag).astype(np.int)
  20. mag = np.mod(mag, flag)
  21. num_barb = np.floor(mag / full).astype(np.int)
  22. mag = np.mod(mag, full)
  23. half_flag = mag >= half
  24. empty_flag = ~(half_flag | (num_flags > 0) | (num_fullflags > 0) |(num_barb > 0))
  25. return num_fullflags,num_flags,num_barb, half_flag, empty_flag

3. 调整set_UVC中相关方法使用

  1. fullflags, flags,barbs, halves, empty = self._find_tails(magnitude,
  2. self.rounding,
  3. **self.barb_increments)
  4. # Get the vertices for each of the barbs
  5. plot_barbs = self._make_barbs(u, v, fullflags, flags,barbs, halves, empty,
  6. self._length, self._pivot, self.sizes,
  7. self.fill_empty, self.flip)

四、测试

  1. import matplotlib.pyplot as plt
  2. fig=plt.figure()
  3. ax=fig.add_subplot(111);
  4. ax.axis([-1,1,-1,1])
  5. ax.set_xticks([])
  6. ax.set_yticks([])
  7. ax.barbs(0,0,30*1.5,40*1.5,length=8,linewidth=0.5)
  8. plt.show()

五、总结

通过本次实践一方面解决了自己实际问题,另一方面锻炼了自己阅读代码的能力,是一次很重要的学习过程,为我的Python之路打下坚实基础。


本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

想观看Matplotlib教学视频,了解更多Matplotlib实用技巧可关注

微信公众账号: MatplotlibClass

今日头条号:Matplotlib小讲堂

Python自学笔记——Matplotlib风羽自定义的更多相关文章

  1. Python自学笔记——matplotlib极坐标.md

    一.极坐标 在平面内取一个定点O,叫极点,引一条射线Ox,叫做极轴,再选定一个长度单位和角度的正方向(通常取逆时针方向).对于平面内任何一点M,用ρ表示线段OM的长度(有时也用r表示),θ表示从Ox到 ...

  2. python自学笔记

    python自学笔记 python自学笔记 1.输出 2.输入 3.零碎 4.数据结构 4.1 list 类比于java中的数组 4.2 tuple 元祖 5.条件判断和循环 5.1 条件判断 5.2 ...

  3. python自学笔记(一)

    我没学过python,通过网上和一些图书资料,自学并且记下笔记. 很多细节留作以后自己做项目时再研究,这样能更高效一些. python基础自学笔记 一.基本输入和输出 pthon3.0用input提示 ...

  4. Matplotlib风羽自定义

    [前言]对于气象专业的小学生来说,风场是预报重要的参考数据,我们所知的风羽有四种:短线代表风速2m/s,长线代表风速4m/s,空心三角代表风速20m/s,实心三角代表风速50m/s.而matplotl ...

  5. python自学笔记一

    之前看过一段时间的小甲鱼零基础自学python,b站上有高清免费资源[av4050443],但是作为零基础实在学得艰难,下载了python核心编程pdf,在这里做一些笔记. 虽然使用的是第二版的教材, ...

  6. Python 自学笔记(一)环境搭建

    一,关于Python的介绍 关于Python的介绍,我不想多说了,网上随便一搜,很多介绍,这里我主要写下我的自学Python的 过程,也是为了促进我能继续学习下去. 二,环境搭建 1,这里我只讲解Wi ...

  7. python 自学笔记(四) 列表

    有几天没有更新博客了,毕竟是自学,最近事情确实比较多,有时候想学的时候反而没时间,到有时间的时候反而不想学.以后得想办法改掉这个缺点,只要有时间就要学习自己想学的东西,希望自学的同学能和我共同交流,其 ...

  8. Python自学笔记-sorted()函数(来自廖雪峰的官网Python3)

    感觉廖雪峰的官网http://www.liaoxuefeng.com/里面的教程不错,所以学习一下,把需要复习的摘抄一下. 以下内容主要为了自己复习用,详细内容请登录廖雪峰的官网查看. 排序算法 排序 ...

  9. 如何深入系统的学习一门编程语言——python自学笔记

    前言 最早接触python的时候,他并没有现在这么火,我也没把他太当回事,那时候我对python的印象就是给运维人员使用的一门很古老的语言,显然随着tensorflow(以下简称tf)的兴起,pyth ...

随机推荐

  1. C# 解析bt种子

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...

  2. OWIN产生的背景以及简单介绍

    OWIN产生的背景以及简单介绍 随着VS2013的发布,微软在Asp.Net中引入了很多新的特性,比如使用新的权限验证模块Identity, 使用Async来提高Web服务器的吞吐量和效率等.其中一个 ...

  3. Entity Framework 5 自定义代码生成模板 转

    Entity Framework 5 发布有一定时间了,但学习资源确实不多,更何况英语差的我,看英语确实费力,不管怎么样,问题还是解决了,查看很多人写的文章(让我看的想放弃,更想找到答案),都没有到到 ...

  4. Linux 安装配置maven3.0 以及搭建nexus私服

    http://carvin.iteye.com/blog/785365 一.软件准备 1.apache-maven-3.0-bin.tar.gz 下载地址:http://www.apache.org/ ...

  5. KMP算法简单回顾

    前言 虽从事企业应用的设计与开发,闲暇之时,还是偶尔涉猎数学和算法的东西,本篇根据个人角度来写一点关于KMP串匹配的东西,一方面向伟人致敬,另一方面也是练练手,头脑风暴.我在自娱自乐,路过的朋友别太认 ...

  6. windows服务安装启动报错误1053:服务没有及时响应启动或控制请求

    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0&qu ...

  7. Helper Method

    ASP.NET MVC 小牛之路]13 - Helper Method 我们平时编程写一些辅助类的时候习惯用“XxxHelper”来命名.同样,在 MVC 中用于生成 Html 元素的辅助类是 Sys ...

  8. 设置控件Enable=false,控件颜色不变

    [System.Runtime.InteropServices.DllImport("user32.dll ")] public static extern int SetWind ...

  9. 【C#基础知识】静态构造函数,来源于一道面试题的理解

    看到园友的一道面试题,很好奇,测试了一下结果. public class A { public static int X=B.Y ; public A() { ++X; } } public clas ...

  10. IOS使用不同父类的 view 进行约束

    最终效果图如下: 很多限制条件都已经应用到了视图中,我们在解释一下: ·在我们的视图控制器的主视图中有两个灰色的视图.两个视图距视图控制器的视图左 边和右边都有一个标准的空白距离.视图的顶部距顶部的视 ...