使用底图绘制纬度/长点

时间:2017-06-11 19:56:32

标签: matplotlib matplotlib-basemap

我正在尝试使用matplotlib和Basemap在地图上绘制点,其中点代表特定建筑物的纬度/经度。我的地图确实绘制了点,但将它们放在错误的位置。当我使用相同的数据并使用Bokeh做同样的事情,而不是matplotlib和底图,我得到正确的情节。

以下是Bokeh中的正确结果: Bokeh Version

这是底图中的INCORRECT结果: Basemap Version

我在StackOverflow的其他地方看到过这样的讨论,这表明这可能与plot()以某种方式“改变”经度这一事实有关。我已经尝试过那里的建议,其中包括以下内容:     lons,lats = m.shiftdata(long,lat) 然后使用移位的数据。这没有任何明显的影响。

我在Basemap和Bokeh中生成两个图的完整示例代码在这里:

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import pandas as pd

from bokeh.plotting import figure, show
from bokeh.sampledata.us_states import data as states
from bokeh.models import ColumnDataSource, Range1d

# read in data to use for plotted points
buildingdf = pd.read_csv('buildingdata.csv')
lat = buildingdf['latitude'].values
long = buildingdf['longitude'].values

# determine range to print based on min, max lat and long of the data
margin = .2 # buffer to add to the range
lat_min = min(lat) - margin
lat_max = max(lat) + margin
long_min = min(long) - margin
long_max = max(long) + margin

# create map using BASEMAP
m = Basemap(llcrnrlon=long_min,
            llcrnrlat=lat_min,
            urcrnrlon=long_max,
            urcrnrlat=lat_max,
            lat_0=(lat_max - lat_min)/2,
            lon_0=(long_max-long_min)/2,
            projection='merc',
            resolution = 'h',
            area_thresh=10000.,
            )
m.drawcoastlines()
m.drawcountries()
m.drawstates()
m.drawmapboundary(fill_color='#46bcec')
m.fillcontinents(color = 'white',lake_color='#46bcec')
# convert lat and long to map projection coordinates
lons, lats = m(long, lat)
# plot points as red dots
m.scatter(lons, lats, marker = 'o', color='r')
plt.show()


# create map using Bokeh
source = ColumnDataSource(data = dict(lat = lat,lon = long))
# get state boundaries
state_lats = [states[code]["lats"] for code in states]
state_longs = [states[code]["lons"] for code in states]

p = figure(
           toolbar_location="left",
           plot_width=1100,
           plot_height=700,
           )

# limit the view to the min and max of the building data
p.y_range = Range1d(lat_min, lat_max)
p.x_range = Range1d(long_min, long_max)
p.xaxis.visible = False
p.yaxis.visible = False
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None

p.patches(state_longs, state_lats, fill_alpha=0.0,
      line_color="black", line_width=2, line_alpha=0.3)

p.circle(x="lon", y="lat", source = source, size=4.5,
         fill_color='red',
         line_color='grey',
         line_alpha=.25
         )
show(p)

我没有足够的声誉点来发布数据链接或将其包含在此处。

1 个答案:

答案 0 :(得分:11)

在底图中,散点将隐藏在fillcontinents后面。删除两行

#m.drawmapboundary(fill_color='#46bcec')
#m.fillcontinents(color = 'white',lake_color='#46bcec')

会告诉你这些要点。因为这可能是不受欢迎的,所以最好的解决方案是使用zorder参数将散点放在地图其余部分的顶部。

m.scatter(lons, lats, marker = 'o', color='r', zorder=5)

enter image description here

这是完整的代码(我想请你在下次提问时将这种可运行的最小例子与硬编码数据包括在一起,因为它可以节省每个人自己发明数据的大量工作)< / EM>:

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import pandas as pd
import io

u = u"""latitude,longitude
42.357778,-71.059444
39.952222,-75.163889
25.787778,-80.224167
30.267222, -97.763889"""

# read in data to use for plotted points
buildingdf = pd.read_csv(io.StringIO(u), delimiter=",")
lat = buildingdf['latitude'].values
lon = buildingdf['longitude'].values

# determine range to print based on min, max lat and lon of the data
margin = 2 # buffer to add to the range
lat_min = min(lat) - margin
lat_max = max(lat) + margin
lon_min = min(lon) - margin
lon_max = max(lon) + margin

# create map using BASEMAP
m = Basemap(llcrnrlon=lon_min,
            llcrnrlat=lat_min,
            urcrnrlon=lon_max,
            urcrnrlat=lat_max,
            lat_0=(lat_max - lat_min)/2,
            lon_0=(lon_max-lon_min)/2,
            projection='merc',
            resolution = 'h',
            area_thresh=10000.,
            )
m.drawcoastlines()
m.drawcountries()
m.drawstates()
m.drawmapboundary(fill_color='#46bcec')
m.fillcontinents(color = 'white',lake_color='#46bcec')
# convert lat and lon to map projection coordinates
lons, lats = m(lon, lat)
# plot points as red dots
m.scatter(lons, lats, marker = 'o', color='r', zorder=5)
plt.show()