Python 子图与底图对应的直方图

Python 子图与底图对应的直方图,python,matplotlib,matplotlib-basemap,Python,Matplotlib,Matplotlib Basemap,下面是一段代码,我必须在底图上绘制地理定位数据。我想在我的底图左侧添加一个直方图,以显示与每个纬度相关的密度 data = np.zeros((5000,3)) data[:,0]=np.random.uniform(low=-180,high=180,size=(5000,)) data[:,1]=np.random.uniform(low=-60,high=90,size=(5000,)) data[:,2] =np.random.uniform(low=0,high=100000,size

下面是一段代码,我必须在底图上绘制地理定位数据。我想在我的底图左侧添加一个直方图,以显示与每个纬度相关的密度

data = np.zeros((5000,3))
data[:,0]=np.random.uniform(low=-180,high=180,size=(5000,))
data[:,1]=np.random.uniform(low=-60,high=90,size=(5000,))
data[:,2] =np.random.uniform(low=0,high=100000,size=(5000,))

fig = plt.figure(facecolor='w')
grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2)
main_ax = fig.add_subplot(grid[:-1, 1:])

m = Basemap(projection = 'cyl', llcrnrlat = -60., urcrnrlat = 90., llcrnrlon = -180., urcrnrlon = 180., resolution ='l')
x, y =m(data[:,0], data[:,1])
m.scatter(x, y, marker='.', s = 0.02, c = data_lac[:,2], cmap = 'hot_r', edgecolor = 'none')
m.fillcontinents(color='grey', lake_color=None, ax=None, alpha=0.1)
parallels=np.arange(-60.,90.,10)
m.drawparallels(parallels, labels =[True, False, False, True], linewidth=0.)
m.drawmeridians(np.arange(-180.,180.,20),labels =[True, False, False, True], linewidth=0. )
m.colorbar()

y_hist = fig.add_subplot(grid[:-1, 0], xticklabels=[], sharey=main_ax)

# histogram on the attached axes
y_hist.hist(data[:,1], 150, histtype='stepfilled', orientation='horizontal', color='blue',alpha=0.2)
y_hist.invert_xaxis()
plt.tight_layout()
plt.show()
我的直方图大小与地图大小和纬度不匹配(如果我只想从-60°到90°)。此外,底图和直方图之间不共享y轴。 我也尝试了GridSpec格式,但结果是一样的


尽管我在评论中链接的答案提供了问题的基本解决方案,但当图形的纵横比“太小”时,可能会出现问题。在这种情况下,即使ytick和ylims是同步的,但由于两个子地块的纵横比不同,所以底图和直方图的高度也不同步。解决此问题的最简单方法是使用轴分隔器,而不是通常的
add_subplot()
方法,就像在上一个示例中所做的那样

结合我之前分享两个情节之间的Ytick,实际上可以得到非常好的结果。为了获得最佳效果,我建议不要使用basemaps
colorbar
函数,而是直接使用带有专用轴的
fig.colorbar
。此外,在我看来,如果只在直方图左侧显示ytick标签,并将其隐藏在底图旁边(解决方案来源),效果会更好。如果不需要,可以使用
分隔器中的
pad
关键字调整直方图和底图之间的距离。附加轴()

将numpy导入为np
从matplotlib导入pyplot作为plt
从mpl_toolkits.basemap导入basemap
从mpl_toolkits.axes_grid1导入使_axes_可定位
数据=np.零((5000,3))
数据[:,0]=np.random.normal(loc=20,scale=30,size=5000,)
数据[:,1]=np.random.normal(loc=50,scale=10,size=5000,)
数据[:,2]=np.random.uniform(低=0,高=100000,大小=(5000,))
##创建仅包含主轴的图形:
图,main_ax=plt.子地块()
m=基线图(
投影='cyl',
llcrnrlat=-60.,urcrnrlat=90。,
llcrnrlon=-180.,urcrnrlon=180。,
决议class='l',
ax=主_ax,
)
x、 y=m(数据[:,0],数据[:,1])
cls=m.散射(
x、 y,,
标记='',s=1,c=data[:,2],
cmap='hot_r',edgecolor='none'
)
m、 填充大陆(颜色为灰色,湖泊颜色为无,ax为无,alpha为0.1)
拉特=北阿兰奇(-60,90,10)
lons=np.arange(-180,180,60)
##没有标签的平行线
m、 drawparallels(板条,标签=[False,False,False,False],线宽=0.1)
m、 DrawMeridian(LON,标签=[假,假,假,真],线宽=0.1)
##生成其他轴实例:
##如果要在地图的左侧添加标签,
##调整衬垫使其可见
分隔器=使轴可定位(主轴)
y_hist=divider.append_轴('left',size='20%',pad='5%',sharey=main_ax)
cax=分隔器。附加_轴(“右”,尺寸=0.1,焊盘=0.1)
##使用fig.colorbar代替m.colorbar
图颜色条(cls,cax=cax)
##附加轴上的直方图
y_hist.hist(数据[:,1],150,histtype='stepfilled',orientation='horizontal',color='blue',alpha=0.2)
y_hist.invert_xaxis()
##y形标签:
_,yticks_data=m(0*lats,lats)
y_历史设置_yticks(yticks_数据)
y_hist.set_yticklabels(['{:>3}$^\circ${}'。格式(

资产负债表(综合(y)),'N'if y>0其他'if y你看到了吗?从某种意义上说,这是我在寻找的东西,但在我看来,这个图可能是动态的,并且遵循主地图的勾号模式。我在我的帖子中添加了一个例子来说明我在寻找什么,我希望它会有所帮助!这是一个我将一个基本地图图与一个简单的线图对齐的例子也可以使用直方图。如果示例不够(例如,如果您需要更多帮助),让我知道,我可以为您的特定问题编写一个示例。非常感谢,我尝试了您的解决方案。它与直方图配合得很好,我非常接近我的期望值。最后两个问题,第一个问题是使用子图似乎将相同的大小赋予每个图形,然后我无法将数据从-180映射到180。第二个问题是颜色条似乎无法自动缩放。这是一个消息错误,但使用fig颜色条可以解决此问题。谢谢
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.axes_grid1 import make_axes_locatable

data = np.zeros((5000,3))
data[:,0] = np.random.normal(loc=20, scale = 30, size=(5000,))
data[:,1] = np.random.normal(loc=50, scale=10, size=(5000,))
data[:,2] =np.random.uniform(low=0,high=100000,size=(5000,))

##create a figure with just the main axes:
fig, main_ax = plt.subplots()

m = Basemap(
    projection = 'cyl',
    llcrnrlat = -60., urcrnrlat = 90.,
    llcrnrlon = -180., urcrnrlon = 180.,
    resolution ='l',
    ax=main_ax,
)

x, y =m(data[:,0], data[:,1])
cls = m.scatter(
    x, y,
    marker='.', s = 1, c = data[:,2],
    cmap = 'hot_r', edgecolor = 'none'
)
m.fillcontinents(color='grey', lake_color=None, ax=None, alpha=0.1)
lats=np.arange(-60.,90.,10)
lons=np.arange(-180.,180.,60)

##parallels without labels
m.drawparallels(lats, labels =[False, False, False, False], linewidth=0.1)
m.drawmeridians(lons,labels =[False, False, False, True], linewidth=0.1 )


##generating the other axes instances:
##if you want labels at the left side of the map,
##adjust pad to make them visible
divider = make_axes_locatable(main_ax)
y_hist = divider.append_axes('left', size='20%', pad='5%', sharey=main_ax)
cax = divider.append_axes('right',size=0.1,pad=0.1)

##use fig.colorbar instead of m.colorbar
fig.colorbar(cls, cax = cax)


## histogram on the attached axes
y_hist.hist(data[:,1], 150, histtype='stepfilled', orientation='horizontal', color='blue',alpha=0.2)
y_hist.invert_xaxis()

##the y-ticklabels:
_,yticks_data = m(0*lats,lats)
y_hist.set_yticks(yticks_data)
y_hist.set_yticklabels(['{: >3}$^\circ${}'.format(
    abs(int(y)), 'N' if y>0 else 'S' if y<0 else ' '
) for y in lats])

##turning off yticks at basemap
main_ax.yaxis.set_ticks_position('none')
plt.setp(main_ax.get_yticklabels(), visible=False)


plt.tight_layout()
plt.show()