在folium中显示栅格数据(不处理数据值)。

时间:2018-06-04 21:31:52

标签: python matplotlib raster folium

我正在尝试使用folium显示栅格类型数据(numpy数组)。这就是我到目前为止所拥有的。

import folium
from folium.plugins import ImageOverlay
import numpy as np
from matplotlib import cm

z = np.random.rand(100, 100)
m = folium.Map([30, -80], zoom_start=6, tiles='stamentoner')
folium.plugins.ImageOverlay(
    image=z,
    name='sample map',
    opacity=1,
    bounds=[[25, -75.], [35., -85.]],
    interactive=False,
    cross_origin=False,
    zindex=1,
    colormap=cm.viridis
).add_to(m)
folium.LayerControl().add_to(m)
m.save('sample.html')

我现在要做的是为z的某些值指定无颜色;例如z< 0.9。我试过了:

z = np.where(z < 0.9, np.nan, z)

但它没有用。纳米细胞仍然有颜色。

2 个答案:

答案 0 :(得分:0)

我认为您可以尝试在导入到传单之前将要屏蔽的值转换为0(或其他nodata值)。 在栅格中将此值设置为nodata。 将图像保存为PNG。 然后导入到传单。

答案 1 :(得分:0)

可能不是最好的方法,但是我有解决方案,而不必先将其另存为PNG。

我假设您有一个带有一些值的NumPy数组。就我而言,该数组为img,它是一个二维数组,具有七个不同的值[0, 1, 2, 3, 4, 5, -128]。这是分类栅格地图,因此我使用定性颜色。

这是我添加栅格图层的方式:

folium.raster_layers.ImageOverlay(img, 
                                  opacity=1, 
                                  bounds = bounds,
                                  colormap=lambda x: raster_to_coloridx[x]).add_to(m)

现在,这里的关键是(如文件的文档中所述)colormap参数也可以采用RGBA值。 RGBA的A是颜色的Alpha,按人类的说法是不透明度。只需将任何颜色的alpha设置为0,您就会得到一种透明的颜色,这就是您想要的。

我的情况比较容易,因为我使用的是定性颜色,所以我要做的就是聪明地定义字典raster_to_coloridx[x]。这是我的方法:

{0: (0.8941176470588236, 0.10196078431372549, 0.10980392156862745, 1.0),
 1: (0.21568627450980393, 0.49411764705882355, 0.7215686274509804, 1.0),
 2: (0.30196078431372547, 0.6862745098039216, 0.2901960784313726, 1.0),
 3: (0.596078431372549, 0.3058823529411765, 0.6392156862745098, 1.0),
 4: (1.0, 1.0, 0.2, 1.0),
 5: (0.6509803921568628, 0.33725490196078434, 0.1568627450980392, 1.0),
 -128: (1, 1, 1, 0)}

很明显,-128是填充值,而其他人的alpha值为1.0,该值将为0。您可以做的是,而不是传递cmap,而是传递几乎是带有扭曲的cmap的函数:

import matplotlib.cm as cm
def get_color(x):
    decimals = 2
    x = np.around(x, decimals=decimals)
    ls = np.linspace(0,1,10**decimals+1)
    if 0 <= x <= 1:
        return cm.get_cmap('viridis')(ls)[np.argwhere(ls==x)]
    elif x==-128:
        return (0, 0, 0, 0)
    else:
        raise ValueError()

此函数采用0到1之间的值(这意味着您必须先对栅格数组进行规范化),将其四舍五入为decimals小数,然后在viridis色彩图中找到相应的值,然后将其作为RGBA数组返回。如果该值为填充值-128,则返回(0,0,0,0)为透明色。否则会引发错误。

下一步是什么?

您仅需按以下方式更新函数(请注意参数colormap):

folium.plugins.ImageOverlay(
    image=z,
    name='sample map',
    opacity=1,
    bounds=[[25, -75.], [35., -85.]],
    interactive=False,
    cross_origin=False,
    zindex=1,
    colormap=lambda x: get_color(x)
).add_to(m)

改进

如果此方法运行缓慢,这是因为针对每个像素调用了该函数,它将重新创建颜色图。您可以使用functools中的修饰符或部分函数来避免这种情况。同样也可以用于参数化小数和/或颜色图。我希望这会有所帮助!