使用茄属植物组合图像

Combine images using a nightshade

嗨 python 和数据可视化专家,

我想使用 m.bluemarble() 图像作为我的 "day" 图像,但后来我想使用不同的 m.warpimage(...) 作为我的 "night" 图像。

像这样:

我想知道我是否可以以某种方式使用 m.nightshade(),但不是只有黑色,而是显示 m.warpimage 产品吗?

import matplotlib.pyplot as plt
from datetime import datetime
from mpl_toolkits.basemap import Basemap
fig, axes = plt.subplots(1, figsize=(12,8))
m = Basemap(projection='cyl', resolution='l', 
            area_thresh=None, ax=axes)
m.bluemarble()
m.warpimage('http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg')
m.nightshade(datetime.utcnow(), alpha=0.5)
m.scatter([-75, 30, 40, 50, 60], [40, 20, 15, 10, -5], color='red', marker='o')
plt.show()

所以,这几乎是我想要的,但它覆盖了原来的蓝色大理石,这不是我想要的。在输出图像中,图像较暗(通过 nightshade 调用),我希望 warpimage 显示出来,但在其他任何地方,我想要原始 bluemarble

有谁知道一个简单的方法来做到这一点?或者,相反,以困难的方式做到这一点,但仍然有一个很酷的输出图像?为了科学。

提前致谢!欢迎任何建议。我有心理障碍...

杰克

我意识到这是一个旧的 post,但是当我想做类似的事情时,我认为我会 post 我可能的解决方案。我是 Python 的新人,所以请原谅编码。我敢肯定它可以 tidied/rewritten 更有效或使用更合适的方法!

来自我的 Jupyter-Notebook:

import matplotlib.pyplot as plt
import datetime
from mpl_toolkits.basemap import Basemap
from matplotlib import path
import numpy as np
%matplotlib inline

def bluemarble_daynight(date,scale):

    # Define Bluemarble and Nightshade objects
    fig, axes = plt.subplots(1, figsize=(12,8))
    m  = Basemap(projection='cyl', resolution= None,
                 area_thresh=None, ax=axes)
    bm = m.bluemarble(scale=scale)
    ns = m.nightshade(date, alpha=0.5)

    bm_rgb = bm.get_array()
    bm_ext = bm.get_extent()

    axes.cla()

    # Get the x and y index spacing
    x = np.linspace(bm_ext[0], bm_ext[1], bm_rgb.shape[1])
    y = np.linspace(bm_ext[2], bm_ext[3], bm_rgb.shape[0])

    # Define coordinates of the Bluemarble image
    x3d,y3d = np.meshgrid(x,y)
    pts     = np.hstack((x3d.flatten()[:,np.newaxis],y3d.flatten()[:,np.newaxis]))

    # Find which coordinates fall in Nightshade 
    # The following could be tidied up as there should only ever one polygon. Although
    # the length of ns.collections is 3? I'm sure there's a better way to do this.
    paths, polygons = [], []
    for i, polygons in enumerate(ns.collections):
        for j, paths in enumerate(polygons.get_paths()):
            #print j, i
            msk = paths.contains_points(pts)

    # Redefine mask
    msk        = np.reshape(msk,bm_rgb[:,:,0].shape)
    msk_s      = np.zeros(msk.shape)
    msk_s[~msk] = 1.

    # Smooth interface between Night and Day
    for s in range(bm_rgb.shape[1]/50): # Make smoothing between day and night a function of Bluemarble resolution
        msk_s = 0.25 * (  np.vstack( (msk_s[-1,:            ], msk_s[:-1, :            ]) )  \
                        + np.vstack( (msk_s[1:,:            ], msk_s[0  , :            ]) )  \
                        + np.hstack( (msk_s[: ,0, np.newaxis], msk_s[:  , :-1          ]) )  \
                        + np.hstack( (msk_s[: ,1:           ], msk_s[:  , -1,np.newaxis]) ) )

    # Define new RGBA array
    bm_rgba = np.dstack((bm_rgb, msk_s))

    # Plot up Bluemarble Nightshade
    m    = Basemap(projection='cyl', resolution= None, 
                   area_thresh=None, ax=axes)
    bm_n = m.warpimage('http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg',scale=scale)
    bm_d = m.imshow(bm_rgba)
    plt.title('Day/Night Map for %s (UTC)' % date.strftime("%d %b %Y %H:%M:%S"))
    plt.show()

date = datetime.datetime(2000,1,1,0,0,0)
bluemarble_daynight(date,0.25)