## Matplotlib 线段宽度的右对齐

Matplotlib 中Text有horizontalAlignment 和 verticalAlignment属性对应文字的水平对齐和垂直对齐方式，但是对于线段（plot），找遍全网却没有找到令线段宽度根据中法线左右对齐的解决方法。

```def segmentOffset(fig, x, y, linewidth, lr="left"):
import numpy as np
import matplotlib.transforms as transforms

r = {"left": (-1, 1), "right": (1, -1)}[lr]
delta = np.squeeze(np.diff([x, y]))
del_p = np.hypot(*delta)
dpi_scale = np.diag(fig.dpi_scale_trans.get_matrix())
dx, dy = delta[::-1] * linewidth / dpi_scale[:2] / del_p / 2.0 * r
offset = transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)
return offset```

```fig, ax = plt.subplots(figsize=(5, 5))
x = [1, 4]
y = [1, 5]
plt.axis("equal")
lw = 10
ax.plot(x, y, color="k", ls=":", lw=2)
ax.plot(x, y, color="g", lw=lw, alpha=0.5, label="origin")
ax.plot(
x,
y,
color="r",
lw=lw,
alpha=0.5,
label="offset_left",
transform=ax.transData + segmentOffset(fig, x, y, lw, lr="left"),
)
ax.legend()```

## Python脚本下台风数据

```import requests
import json
import os
from urllib import parse as URL_PARSE

url_search = r"http://typhoon.zjwater.gov.cn/Api/TyphoonSearch/"
url_info   = r"http://typhoon.zjwater.gov.cn/Api/TyphoonInfo/"
output_path= r"./"

def getTYinfo(str):
r = requests.get(url_info + str[:6])
if r.status_code == 200:
data = r.json()
savePath = os.path.join(output_path + str + ".json")
print("Typhoon Info ", str, "get, save in " + savePath)
else:

def main():
s = input("Input search information: ")
if not s:
print("Incorrect input. Quiting")
return
r = requests.get(url_search + URL_PARSE.quote(s, encoding="GBK"))
info = r.json()
for i, sg  in enumerate(info):
print(i, sg['name'])
s = input("Select ids(seperate with [Space]):").split()
spl = [int(v) for v in s]
for i in spl:
try:
getTYinfo(info[i]['name'])
except Exception as e:
pass

if __name__ == "__main__":
main()
```

## shapely&非结构化网格：随机生成点产生三角形并融合

```import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import MultiPoint
from shapely.ops import triangulate
from descartes.patch import PolygonPatch
from functools import reduce

points_num = 15
x = np.random.rand(points_num)
y = np.random.rand(points_num)
points = MultiPoint(list(zip(x, y)))
triangles = triangulate(points)
plt.figure()
for triangle in triangles:
patch = PolygonPatch(triangle, alpha=0.5, zorder=2)
for point in points:
plt.plot(point.x, point.y, 'o', color='grey')
plt.xlim((0,1))
plt.ylim((0,1))

poly = reduce(lambda x, y: x.union(y), triangles)
plt.figure()
outline = poly.boundary.coords.xy
plt.plot(*outline, 'r')
plt.xlim((0,1))
plt.ylim((0,1))```

## Image copy from Clipboard

The win32clipboard module provides method of getting content from clipboard. But, when it comes to image content, bytes data are returned and are hard to convert to image type(involving Bitmap Header and ‘PIL.Image.frombytes() ‘ requires size though is unknown).

However, PIL module offers function can grab image from clipboard.

```# from PIL/ImageGrab.py
...
def grabclipboard():
if sys.platform == "darwin":
fh, filepath = tempfile.mkstemp('.jpg')
os.close(fh)
commands = [
"set theFile to (open for access POSIX file \""+filepath+"\" with write permission)",
"try",
"write (the clipboard as JPEG picture) to theFile",
"end try",
"close access theFile"
]
script = ["osascript"]
for command in commands:
script += ["-e", command]
subprocess.call(script)

im = None
if os.stat(filepath).st_size != 0:
im = Image.open(filepath)
return im
else:
data = Image.core.grabclipboard()
if isinstance(data, bytes):
from . import BmpImagePlugin
import io
return BmpImagePlugin.DibImageFile(io.BytesIO(data))
return data```

So, ‘BmImagePlugin.DibImageFile()’ is exactly what we need.

```import win32clipboard as w
from PIL import Image, BmpImagePlugin
import io
#
w.OpenClipboard()
if w.IsClipboardFormatAvailable(w.CF_DIB):
c = w.GetClipboardData(w.CF_DIB)
im = BmpImagePlugin.DibImageFile(io.BytesIO(c))
im.show() # or other operations
w.CloseClipboard()```

## 多线程批量下载ASCAT风场数据

`ftp进不去，只能用http接口这样子。主页：http://www.remss.com/missions/ascat/说明：http://data.remss.com/ascat/metopa/readme_ASCAT_metopA.txtbytemap格式数据：http://data.remss.com/ascat/metopa/bmaps_v02.1/`
```from bs4 import BeautifulSoup
import requests
import os
import time

global count
count = 0

domain = r"http://data.remss.com"
urlprefix = r"/ascat/metopa/bmaps_v02.1/y2018/m"

global count
count += 1
id = count
filename = url.split('/')[-1]
r = requests.get(url, stream=True)
for chunk in r.iter_content(chunk_size=1024*1024):
if chunk:
f.write(chunk)
f.close()

for m in range(1, 13):
url = domain + urlprefix + "%02d" % m
r = requests.get(url)
r.encoding = "utf-8"
soup = BeautifulSoup(r.text)
print(m)
for item in soup.select("a"):
if item['href'].endswith('1.gz'):
downlink = domain + item['href']
r.close()

for t in threads:
t.start()
while True:
break
time.sleep(0.1)```

## 记笔记——Python、Matplotlib、Basemap

### Basemap：

```def plotbasemap(self, ...):
if not self.m:
self.fig = plt.figure(figsize=(xx,xx))
map = Basemap(...)
...
self.m = pickle.dumps(map)
return map

```import pickle
Dataset = ...
pickle.dump(Dataset, open('save.txt','wb')

### 数据转化, DictInList -> ListInDict:

```[
{
'a' : 1,
'b' : -1
},
{
'a' : 2,
'b' : -2
},
{
'a' : 3,
'b' : -3
}
]```

```{
'a' : [1, 2, 3],
'b' : [-1, -2, -3]
}```

```def dataFormatConvert(data):
return { key : [ p[key] for p in data ] for key in data[0].keys() } if type(data) == list else ...```

## Safari下载文件名url编码转义

```#!/usr/bin/python
# -*- coding: UTF-8 -*-

import urllib
import os
import re

path='xxx/xxx/xx'

for(root,dirs,files) in os.walk(path):
for filename in files:
print root
if re.match('%*%',filename):
os.rename(root+'/'+filename,root+'/'+urllib.unquote(filename).replace('+',' '))```