2019/05/07現在、Python3ではエラーでBasemapのimportすら出来なくなりました。
http://ty21ky.web.fc2.com/python/
で、cartopy版の世界地図を始めました。
数日前に今迄インストールしたライブラリに新しいバージョンが沢山ありましたので、全てのライブラリを最新のバージョンにバージョンアップしました。
バージョンアップする前は、普通に動作していましたが、アップ後は動作しなくなりました。
現在のところ、原因はバージョンアップしたライブラリが悪いのかどうか不明です。
BaseMap関係のPython3のライブラリはバージョンアップしない方がよいようです。また、これからインストールする人は最新の物をインストールすると動作しません。
ひょっとして、もうBasemapはインストール出来ないかもしれない。
海外のサイトで、Basemapは廃止予定なのでcartopyを勉強してくださいと書いてました。
Python2では、使用できるようです。(ライブラリのバージョンアップしていません)
matplotlib(3.0.3)をアンインストールし、元の(2.2.2)をインストールし実行すると、次は
「AttributeError: module 'pyproj' has no attribute 'pyproj_datadir'」
何か沢山元に戻す必要があるようです。
実行した環境
Ubuntu Stdio 17.10 ー> 18.04LTSにアップグレード
Python 2.7.14 ー> 2.7.15rc1
Python 3.6.3 ー> 3.6.5
18.04LTSにアップグレードしPython2で動作していたものが、'ascii'codec can't・・・で動作しないものもあります。
また、Python3で動作するようになりました。
いくつか実行しましたが、ほとんどのプログラムは動作して、エラーはほんの一部だけでした。
Python2の方で'ascii'codec can'tエラーがでるものは、importの前に
try:
#Python2の場合
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
except NameError:
pass #Python3
を入れることで解決しました。
俺的備忘録 〜なんかいろいろ〜 さん ありがとうございます。
https://orebibou.com/2017/08/python%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%A7%E3%80%8Eunicodedecodeerror-ascii-codec-cant-decode-byte-0xc3%E3%80%8F%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C/
'ascii'codec can'tエラーが出るものと、出ないものがある。????
インストール(Python 2.7.14)
sudo apt install python-matplotlib
sudo apt install python-mpltoolkits.basemap
Python 3.6.3 ー> 3.6.5
sudo apt install python3-matplotlib
sudo apt install python3-mpltoolkits.basemap
でインストール出来るのですが、エラーがでて動作しません。(コメント欄に書きましたが動作する場合もあるようです。)
アップグレード後、Python3で動作するようになりました。
# !/usr/bin/python3
# coding: UTF-8
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
# import numpy as np
map = Basemap(projection='ortho', lat_0=35, lon_0=135,
resolution='l', area_thresh=1000.0)
map.drawcoastlines() #海岸線
center = 6378100 # (m) 地球中心座標
spece = 10000 #単位(m) #projection = 'ortho'の場合、地球の輪郭線の上下左右が線幅の1/2が表示範囲からはみ出て消えているため、表示範囲を広げる。
plt.axis([-spece, spece+center*2, -spece, spece+center*2]) #グラフの範囲(表示範囲)を広げる
# plt.savefig('xxx.png') #pngで保存
plt.show() #ウインドウで表示
# plt.close() #plt.savefigで連続して行う場合は必ず必要。クローズしてメモリを開放する。
projection = 'cea' 正積円筒図法
projection = 'mbtfpq' McBryde-Thomas Flat-Polar Quartic 図法
projection='aeqd' 正距方位図法
projection = 'sinu 正弦曲線図法
projection = 'moll' モルワイデ図法
projection = 'gall' ゴール図法
projection = 'mill' ミラー図法
projection = 'merc' メルカトル図法(高緯度に向かうにつれ距離や面積が拡大される)
projection = 'cyl' Cylindrical Equidistant(極地域の縮尺と面積の歪みは、メルカトル図法よりも小さくなります。グラフの座標は東経・北緯の表示になります。)
projection = 'hammer' Hammer
projection = 'geos' Geostationary
projection = 'nsper' Near-Sided Perspective
projection = 'eck4' エケルト図法
projection = 'kav7' Kavrayskiy VII
projection = 'ortho' 正射投影(地球表面を平面に対して正射影して描かれる地図)
projection = 'vandg' ヴァン・デル・グリンテン図法
projection = 'robin' ロビンソン図法(楕円?形の地球)
lat_0 = 0.0 北緯(南緯の場合はマイナス)
lon_0 = 135.0 東経(西経でも良い。この場合はマイナス)
resolution = 'c' 荒い (早い)
resolution = 'l' low
resolution = 'i' 中間
resolution = 'h' high
resolution = 'f' full (非常に時間がかかる)
area_thresh = 0.0 〜 10000.0(これ以上になると大きな島が消えていく)
数値が小さいほうが、小さな島も表示されるが、時間もかかる。
map.bluemarble() 色を指定しないでこれを指定すると衛星写真
map.shadedrelief() 標高図(地球儀のようになる)
map.etopo() 陸地、海洋地形図
map.drawcountries() 国境線
map.drawrivers() 河川の描画
map.drawmapboundary(fill_color='aqua') #これだけを指定すると陸も海も'aqua'(水色)になる。
map.fillcontinents(color='coral',lake_color='aqua') #陸地と湖の色の指定。
map.drawmapboundary() 地図投影領域の周囲に境界線を描画し、必要に応じて領域の内側を塗りつぶします。
map.drawmeridians(np.arange(0, 360, 10)) #緯線 表示 例.10度毎
,labels=[True,False,False,True] を指定すると東経のラベル表示(地図の種類により表示されないものがある)
map.drawparallels(np.arange(-90, 90, 10)) #経線 表示 例.10度毎
,labels=[False,True,True,False] を指定すると北緯のラベル表示
map.drawparallels(np.arange(0, 1, 1),color='red',linestyle='solid') #赤道
サンプルプログラム
上記のサイトにたくさんあります。
https://qiita.com/sakaia/items/36c92d14942c3458bb56
ここでは、世界銀行のデータを世界地図上に表示出来る。
MotoGPのサーキットの位置を地図上にプロットする
circuit.pyのあるフォルダにdatasetsフォルダを作成し、circuit_data.csvを保存する。
latitude,longitude,name
34.845602,136.539017,suzuka circuit
36.531433,140.224618,Twin Ring Motegi
25.486119,51.452865,Lusail Race Track
-27.512414,-64.917640,Autódromo internacional Termas De Rio Hondo
30.134451,-97.635765,Circuit of the Americas
36.709213,-6.033803,Circuito de Jerez
47.953644,0.213421,Circuit Bugatti
43.997518,11.372029,Mugello Circuit
41.568231,2.257314,Circuit de Barcelona-Catalunya
52.958256,6.522449,TT Circuit Assen
50.791774,12.688464,sachsenring-circuit
49.203901,16.44578,Brno Circuit
47.220266,14.764772,Red Bull Ring
-37.621419,145.02113,Silverstone Circuit
43.961893,12.684494,Misano World Circuit Marco Simoncelli
41.078284,-0.204513,MotorLand Aragón
14.957992,103.085011,Chang International Circuit
-38.496949,145.229462,Phillip Island Grand Prix Circuit
2.759404,101.731896,Sepang International Circuit
39.48688,-0.629795,Ricardo Tormo Circuit
# !/usr/bin/python
import csv
filename = 'datasets/circuit_data.csv'
# Create empty lists for the latitudes and longitudes.
lats, lons = [], []
# Read through the entire file, skip the first line,
# and pull out just the lats and lons.
with open(filename) as f:
# Create a csv reader object.
reader = csv.reader(f)
# Ignore the header row.
next(reader)
# Store the latitudes and longitudes in the appropriate lists.
for row in reader:
lats.append(float(row[0])) #latitude
lons.append(float(row[1])) #longitude
# Build Map
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
# make sure the value of resolution is a lowercase L,
# for 'low', not a numeral 1
map = Basemap(projection='robin', lat_0=0, lon_0=150,
resolution='l', area_thresh=1000.0)
map.drawcoastlines()
map.drawcountries()
map.fillcontinents(color='gray')
map.drawmapboundary()
plt.title('2018 MotoGP circult + suzuka circuit')
map.drawmeridians(np.arange(0, 360, 10))
map.drawparallels(np.arange(-90, 90, 10))
x,y = map(lons, lats)
map.plot(x, y, 'ro', markersize=3)
plt.show()
サーキット名を表示
ズームしないと文字が重なります。
変更点
lats, lons, name1 = [], [], [] #変更
for row in reader:
lats.append(float(row[0])) #latitude
lons.append(float(row[1])) #longitude
name1.append(row[2]) #circuit name #追加
x,y = map(lons, lats)
map.plot(x, y, 'ro', markersize=3)
for i in range(len(name1)): #追加
plt.text(x[i], y[i], " " + name1[i], fontsize=12, color='red') #追加
plt.show()
text()は、どうもリストが使えないようなのでfor文で繰り返す。
サーキット名の1文字目がドットに隠れるので、前にスペースを入れる。
y座標に値を追加すると、ズームで拡大すると文字がドットからズームするたびに離れていきます。
ズームはルーペ ボタンを何回も押さないとズーム出来ない??