使用Python/Basemap绘图时,线条没有出现在图形上。

3
抱歉,如果这个问题很简单的话,我是一个新手,正在使用Python和Basemap。无论如何,我正在尝试在地图上(图表)绘制20个飓风的路径。地图本身和图例都显示得很完美,但飓风的路径没有显示出来。此外,我没有收到任何回溯消息,但我想我知道我的问题可能出在哪里。请问有人能告诉我哪里出错了吗?
以下是CSV文件的示例:
Year, Name, Type, Latitude, Longitude
1957,AUDREY,HU, 21.6, 93.3
1957,AUDREY,HU,22.0,  93.4
1957,AUDREY,HU,22.6,  93.5
1969,AUDREY,HU,28.2,99.6
1957,AUDREY,HU,26.5,93.8
1957,AUDREY,HU,27.9,93.8
1957,AUDREY,HU,29.3,95
1957,AUDREY,HU,27.9,93.8
1957,AUDREY,HU,29.3,93.8
1957,AUDREY,HU,30.7,93.5
1969,CAMILLE,HU, 21.6,99.3
1969,CAMILLE,HU,22.0,98.4
1969,CAMILLE,HU,22.6,90.5
1969,CAMILLE,HU,23.2,93.6

这是我目前的代码:

这里是我目前的代码:

import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import csv, os, scipy
import pandas
from PIL import *


data = np.loadtxt('louisianastormb.csv',dtype=np.str,delimiter=',',skiprows=1)
'''print data'''
fig = plt.figure(figsize=(12,12))

ax = fig.add_axes([0.1,0.1,0.8,0.8])

m = Basemap(llcrnrlon=-100.,llcrnrlat=0.,urcrnrlon=-20.,urcrnrlat=57.,
            projection='lcc',lat_1=20.,lat_2=40.,lon_0=-60.,
            resolution ='l',area_thresh=1000.)

m.bluemarble()
m.drawcoastlines(linewidth=0.5)
m.drawcountries(linewidth=0.5)
m.drawstates(linewidth=0.5)

# Creates parallels and meridians
m.drawparallels(np.arange(10.,35.,5.),labels=[1,0,0,1])
m.drawmeridians(np.arange(-120.,-80.,5.),labels=[1,0,0,1])
m.drawmapboundary(fill_color='aqua')
color_dict = {'AUDREY': 'red', 'ETHEL': 'white', 'BETSY': 'yellow','CAMILLE': 'blue', 'CARMEN': 'green','BABE': 'purple', }


colnames = ['Year','Name','Type','Latitude','Longitude']
data = pandas.read_csv('louisianastormb.csv', names=colnames)
names = list(data.Name)
lat = list(data.Latitude)
long = list(data.Longitude)
colorName = list(data.Name)
#print lat
#print long
lat.pop(0)
long.pop(0)
colorName.pop(0)
latitude= map(float, lat)
longitude = map(float, long)
x, y = m(latitude,longitude)
#Plots points on map
for colorName in color_dict.keys():
    plt.plot(x,y,linestyle ='-',label=colorName,color=color_dict[colorName], linewidth=5 )
    lg = plt.legend()
    lg.get_frame().set_facecolor('grey')
plt.show()

你能否上传CSV数据文件,或者只是一个最小工作示例的剥离版本? - nye17
@nye17 当然可以,我刚刚添加了 CSV 文件的样例。我无法上传整个文件。 - mikez1
2个回答

5

你的代码有两个问题:

i. 你输入的经度应该是负数,以符合你定义的底图边界,所以在转换为x和y之前,请添加以下内容

longitude = [-i for i in longitude]

你好,你的坐标转换代码有误,应该在参数列表中交换经度和纬度。

x, y = m(longitude, latitude)

替代

x, y = m(latitude,longitude)

编辑:

好的,请查看下面完整的代码,并注意我相对于你所做的更改。

# Last-modified: 21 Oct 2013 05:35:16 PM

import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import csv, os, scipy
import pandas
from PIL import *


data = np.loadtxt('louisianastormb.csv',dtype=np.str,delimiter=',',skiprows=1)
'''print data'''
fig = plt.figure(figsize=(12,12))

ax = fig.add_axes([0.1,0.1,0.8,0.8])

m = Basemap(llcrnrlon=-100.,llcrnrlat=0.,urcrnrlon=-20.,urcrnrlat=57.,
            projection='lcc',lat_1=20.,lat_2=40.,lon_0=-60.,
            resolution ='l',area_thresh=1000.)

m.drawcoastlines(linewidth=0.5)
m.drawcountries(linewidth=0.5)
m.drawstates(linewidth=0.5)
# m.bluemarble(ax=ax)

# Creates parallels and meridians
m.drawparallels(np.arange(10.,35.,5.),labels=[1,0,0,1])
m.drawmeridians(np.arange(-120.,-80.,5.),labels=[1,0,0,1])
m.drawmapboundary(fill_color='aqua')
color_dict = {'AUDREY': 'red', 'ETHEL': 'white', 'BETSY': 'yellow','CAMILLE': 'blue', 'CARMEN': 'green','BABE': 'purple', }

colnames = ['Year','Name','Type','Latitude','Longitude']
data = pandas.read_csv('louisianastormb.csv', names=colnames)
names = list(data.Name)
lat = list(data.Latitude)
long = list(data.Longitude)
colorNames = list(data.Name)
#print lat
#print long
lat.pop(0)
long.pop(0)
colorNames.pop(0)
latitude= map(float, lat)
longitude = map(float, long)
# added by nye17
longitude = [-i for i in longitude]
# x, y = m(latitude,longitude)
x, y = m(longitude,latitude)
# convert to numpy arrays
x = np.atleast_1d(x)
y = np.atleast_1d(y)
colorNames = np.atleast_1d(colorNames)
#Plots points on map
for colorName in color_dict.keys():
    plt.plot(x[colorName == colorNames],y[colorName == colorNames],linestyle ='-',label=colorName,color=color_dict[colorName], linewidth=5 )
    lg = plt.legend()
    lg.get_frame().set_facecolor('grey')
plt.show()

enter image description here


非常感谢!!!然而现在所有的线都是用同一种颜色绘制的。我该如何解决这个问题,使得飓风的路径与我的颜色字典中的颜色匹配呢?例如奥德里飓风的路径应该是红色的,埃塞尔的路径应该是蓝色的,等等。 - mikez1
@mikez1 每个帖子应该只提出一个问题。如果这个答案解决了你在原始帖子中提出的问题,那么你应该接受它(大灰色复选框)。如果你有更多或新的问题,你应该创建一个新的问题帖子。 - tacaswell
1
@mikez1 你似乎是新来的,所以不要太担心。一个线程只提出一个问题的逻辑是为了使网站对未来的读者尽可能有用。这也有助于不让回答者发疯,当目标不断变化时,这是非常令人沮丧的。 - tacaswell
@nye17 感谢您的所有帮助。我还有一个问题,但我会创建另一个问题线程来询问。 - mikez1
@mikez1 不用了,只需要检查我上面的代码 --- 我使用你的字典定义了不同颜色来绘制每个飓风的路径。 - nye17
显示剩余2条评论

1
我认为你的困难不在Basemap上,而在于绘图。你需要找到对应于飓风Z的x/y点,然后仅以特定颜色c绘制这些点。然后找到对应于下一个飓风的点等等...
以下内容虽然没有使用Basemap数据结构,但应该可以提供一个基础来根据某个选择器向量绘制子集点的起点。
#given a list of x,y coordinates with a  label we'll plot each line individually

#first construct some points to plot
x1 = [1,1.1,1.2,1.3, 2.0,2.2,2.3, 4,3.9,3.8,3.7]
y1 = [5,5.1,5.2,5.3, 6.0,6.2,6.3, 2,2.1,2.2,2.3]
pointNames = []
#generate some labels
pointNames.extend(['a']*4)
pointNames.extend(['b']*3)
pointNames.extend(['c']*4)

#make things easy by casting to numpy arrays to allow for easier indexing
x1 = numpy.array(x1)
y1 = numpy.array(y1)
pointNames = numpy.array(pointNames)

for elem in ['a','b','c']:
  selector = pointNames==elem
  subsetX = x1[selector]
  subsetY = y1[selector]
  #now plot subsetX vs subsetY in color Z
  plot(subsetX,subsetY,'*-')

show()

好的,感谢你的回复。我想我明白你的意思了,但是我有一个包含20个飓风、类型和坐标等信息的文件。是否有一种简单的方法可以根据飓风名称将所有坐标分组并绘制它们? - mikez1
在这种情况下,您可以使用set函数来获取唯一的字符串名称(飓风)。 s1 = set(['a','b','c','c'])会得到s1:('a','b','c')作为元组。您可以循环遍历每个元素for elem in s1。在您的案例中,pointNames是字符串名称的列表/数组。因此,您将执行s1 = set(names)以获取唯一的飓风名称,然后对其进行循环处理。 - Paul
在我的代码中,我已经有一个颜色字典(color_dict),其中包含飓风的名称。根据我上面的代码,这是否正确:(我使用n1,因为names已经在我的代码中使用)for n1, track in data.groupby('Name'): latitude = track.Lat.values longitude = track.Lon.values #将纬度和经度转换为坐标X和Y x, y = m(longitude, latitude) #在地图上绘制点 pl.plot(x,y,'-', label=n1, color=colors_dict[n1]) - mikez1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接