gpt4 book ai didi

python - 对与 basemap Python 绘图相对应的直方图进行子绘制

转载 作者:行者123 更新时间:2023-12-01 08:12:38 25 4
gpt4 key购买 nike

这是我必须在 basemap 上绘制地理定位数据的代码。我想在 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=(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()

我的直方图大小存在问题,它与 map 大小和纬度不匹配(如果我只想从 -60° 到 90°)。此外, basemap 和直方图之间不共享 y 轴。我也尝试过使用 GridSpec 格式,但结果是相同的。

enter image description here

最佳答案

尽管我在评论中链接的答案提供了该问题的原则解决方案,但当图形的长宽比“太小”时,可能会出现问题。在这种情况下,即使 yticks 和 ylims 同步, basemap 和直方图的高度也不同步,因为两个子图的纵横比不同。解决此问题的最简单方法是使用轴分隔符而不是通常的 add_subplot() 方法,如 this answer 的最后一个示例中所做的那样。 .

与我之前的suggested solution有关为了分享两个图之间的 yticks,实际上可以获得非常简洁的结果。为了获得最佳结果,我建议不要使用 basemap colorbar 函数,而是直接使用 fig.colorbar 以及颜色条的专用轴。另外,(在我看来)如果您仅在直方图左侧显示 ytick 标签并将它们隐藏在 basemap 旁边(来自 here 的解决方案),它看起来最好。如果不需要,您可以使用 divider.append_axes() 中的 pad 关键字调整直方图和 basemap 之间的距离。

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()

最终结果真正同步了子图高度和 yticks(也在调整图形大小时),如下所示:

result of the above code

关于python - 对与 basemap Python 绘图相对应的直方图进行子绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55143860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com