在 matplotlib 底图投影上绘制椭圆

2024-03-28

我正在尝试在底图投影上绘制椭圆。要画一个像多边形一样的圆,有tissot用于绘图的函数天梭的指标' http://en.wikipedia.org/wiki/Tissot%27s_indicatrix如下例所示。

from mpl_toolkits.basemap import Basemap

x0, y0 = 35, -50
R = 5

m = Basemap(width=8000000,height=7000000, resolution='l',projection='aea', 
    lat_1=-40.,lat_2=-60,lon_0=35,lat_0=-50)
m.drawcoastlines()
m.tissot(x0, y0, R, 100, facecolor='g', alpha=0.5)

但是,我有兴趣以以下形式绘制省略号(x-x0)**2/a**2 + (y-y0)**2/2 = 1。另一方面,要在常规笛卡尔网格上绘制省略号,我可以使用以下示例代码:

import pylab
from matplotlib.patches import Ellipse

fig = pylab.figure()
ax = pylab.subplot(1, 1, 1, aspect='equal')

x0, y0 = 35, -50
w, h = 10, 5
e = Ellipse(xy=(x0, y0), width=w, height=h, linewidth=2.0, color='g')
ax.add_artist(e)
e.set_clip_box(ax.bbox)
e.set_alpha(0.7)
pylab.xlim([20, 50])
pylab.ylim([-65, -35])

有没有一种方法可以在底图投影上绘制省略号,其效果类似于tissot?


经过数小时分析底图的源代码tissot函数,学习一些属性ellipses http://en.wikipedia.org/wiki/Ellipse经过大量的调试,我找到了解决问题的方法。我用一个名为的新函数扩展了底图类ellipse如下,

from __future__ import division
import pylab
import numpy

from matplotlib.patches import Polygon
from mpl_toolkits.basemap import pyproj
from mpl_toolkits.basemap import Basemap

class Basemap(Basemap):
    def ellipse(self, x0, y0, a, b, n, ax=None, **kwargs):
        """
        Draws a polygon centered at ``x0, y0``. The polygon approximates an
        ellipse on the surface of the Earth with semi-major-axis ``a`` and 
        semi-minor axis ``b`` degrees longitude and latitude, made up of 
        ``n`` vertices.

        For a description of the properties of ellipsis, please refer to [1].

        The polygon is based upon code written do plot Tissot's indicatrix
        found on the matplotlib mailing list at [2].

        Extra keyword ``ax`` can be used to override the default axis instance.

        Other \**kwargs passed on to matplotlib.patches.Polygon

        RETURNS
            poly : a maptplotlib.patches.Polygon object.

        REFERENCES
            [1] : http://en.wikipedia.org/wiki/Ellipse


        """
        ax = kwargs.pop('ax', None) or self._check_ax()
        g = pyproj.Geod(a=self.rmajor, b=self.rminor)
        # Gets forward and back azimuths, plus distances between initial
        # points (x0, y0)
        azf, azb, dist = g.inv([x0, x0], [y0, y0], [x0+a, x0], [y0, y0+b])
        tsid = dist[0] * dist[1] # a * b

        # Initializes list of segments, calculates \del azimuth, and goes on 
        # for every vertex
        seg = [self(x0+a, y0)]
        AZ = numpy.linspace(azf[0], 360. + azf[0], n)
        for i, az in enumerate(AZ):
            # Skips segments along equator (Geod can't handle equatorial arcs).
            if numpy.allclose(0., y0) and (numpy.allclose(90., az) or
                numpy.allclose(270., az)):
                continue

            # In polar coordinates, with the origin at the center of the 
            # ellipse and with the angular coordinate ``az`` measured from the
            # major axis, the ellipse's equation  is [1]:
            #
            #                           a * b
            # r(az) = ------------------------------------------
            #         ((b * cos(az))**2 + (a * sin(az))**2)**0.5
            #
            # Azymuth angle in radial coordinates and corrected for reference
            # angle.
            azr = 2. * numpy.pi / 360. * (az + 90.)
            A = dist[0] * numpy.sin(azr)
            B = dist[1] * numpy.cos(azr)
            r = tsid / (B**2. + A**2.)**0.5
            lon, lat, azb = g.fwd(x0, y0, az, r)
            x, y = self(lon, lat)

            # Add segment if it is in the map projection region.
            if x < 1e20 and y < 1e20:
                seg.append((x, y))

        poly = Polygon(seg, **kwargs)
        ax.add_patch(poly)

        # Set axes limits to fit map region.
        self.set_axes_limits(ax=ax)

        return poly

这个新功能可以立即使用,如下例所示:

pylab.close('all')
pylab.ion()

m = Basemap(width=12000000, height=8000000, resolution='l', projection='stere',
            lat_ts=50, lat_0=50, lon_0=-107.)
m.drawcoastlines()
m.fillcontinents(color='coral',lake_color='aqua')
# draw parallels and meridians.
m.drawparallels(numpy.arange(-80.,81.,20.))
m.drawmeridians(numpy.arange(-180.,181.,20.))
m.drawmapboundary(fill_color='aqua') 
# draw ellipses
ax = pylab.gca()
for y in numpy.linspace(m.ymax/20, 19*m.ymax/20, 9):
    for x in numpy.linspace(m.xmax/20, 19*m.xmax/20, 12):
        lon, lat = m(x, y, inverse=True)
        poly = m.ellipse(lon, lat, 3, 1.5, 100, facecolor='green', zorder=10,
            alpha=0.5)
pylab.title("Ellipses on stereographic projection")

Which has the following outcome: Sample figure

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 matplotlib 底图投影上绘制椭圆 的相关文章

随机推荐

  • 使用php触发另一个php脚本,然后忽略

    我正在尝试弄清楚该怎么做是这样的 我有一个 php 文件 让我们调用trigger php运行一些 php 代码来启动我们将调用的另一个 php 文件backgroundProcess php开始处理 虽然trigger php需要忽略发生
  • 新手:“rake -T”时出现错误消息

    我在用红宝石企业版对于我的项目 当我检查我所有的耙任务通过运行命令rake T 我收到以下错误消息 You have already activated rake 0 9 2 2 but your Gemfile requires rake
  • Spring Security 访问因缺少角色而被拒绝记录

    对于 Spring Security 中的访问被拒绝登录 是否有开箱即用的解决方案 我想要的基本上是显示用户在收到访问被拒绝异常时缺少哪个角色 如果没有 我必须走上拥有自己的 accessDeniedHandler 的道路 如何访问在该控制
  • RESTful 资源和正交资源问题

    如果我使用的 3 层应用程序具有通过 HTTP 访问的中间层中的面向 RESTful 资源的服务 那么向 UI 层提供正交资源的最佳方式是什么 一个例子是 用户 资源 它具有一个国家 地区的字段 属性 现在在 UI 层中编辑用户时 我希望能
  • WordPress,使用 cookie 进行类别重定向

    我想要实现的目标 当用户访问该网站并选择特定类别时 他们下次访问该网站 回访用户 时 该页面将在该类别部分打开 我认为 通过在访问者单击类别链接 或加载类别页面时 时设置 cookie 这将相当容易做到 当它们返回以下时间时 将读取 coo
  • 在 Django/mod_wsgi 虚拟环境中配置 WSGIPythonHome 的问题

    我在 Windows 10 上运行 Python 3 7 1 和 Apache 2 4 38 我设置了一个虚拟环境 其中包含通过 pip 安装的 Django 2 2 5 和 mod wsgi 4 6 5 在 httpd conf 内部 我
  • 如何获取字符串中所有匹配的位置?

    我有一个专栏flag acumu在 PostgreSQL 的表中 其值如下 SSNSSNNNNNNNNNNNNNNNNNNNNNNNNNNNNSNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN 我需要用 S 显
  • “user-images.githubusercontent.com”上的图像可以删除吗?

    我不小心在 GitHub 上上传了一张我不想放的图片 我原以为出于示例目的 我已经从上传的图像中删除了私人信息 但私人信息仍然存在 它包含诸如主机名之类的内容 我希望这些内容不是公开的 有没有办法从 github 的图像注册表中删除该图像
  • 到本地主机的 New-PSSession 失败

    我有一个打开本地主机远程会话的脚本 我需要这个来从登录脚本中在某些设备上安装 NuGet Username Admin Password ConvertTo SecureString adminPW AsPlainText Force ad
  • getElementsByClassName onclick 问题[重复]

    这个问题在这里已经有答案了 我在用着罗伯特 尼曼的 http robertnyman com 2008 05 27 the ultimate getelementsbyclassname anno 2008 脚本来获取文档中具有相同类的所有
  • 使用非 root 且无需 CPAN 安装 Perl 模块和依赖项

    我一直在为我的工作编写 Perl 脚本 而我工作的机器使安装 Perl 模块变得困难 我们不能有gcc出于安全原因 在我的机器上 所以对于大多数模块 我无法使用 CPAN 来安装模块 我无权访问 root 帐户 通常 当我想安装模块时 我会
  • 朱莉娅:当我有情节时如何找到最佳拟合曲线/方程?

    朱莉娅 当我有情节时如何找到最佳拟合曲线 方程 我有一个用地图绘制的图 但我需要找到一个适合这个的二次方程 正如评论中所说 情节在这里并不重要 只有数据本身是 您可以使用诸如GLM构建数据的 广义 线性模型 并可能绘制它们或使用它们来预测新
  • 请求的运行时 (python-) 不适用于此堆栈 (heroku-20)

    我在尝试通过 Heroku 部署这个 Flask 应用程序时遇到了困难 我研究了多种方法来解决这个问题 但似乎找不到一种可行的方法 这就是当我推动时我得到的git push heroku master remote gt Building
  • Dev-C++ 输入已跳过

    include
  • .NET 4.0 解决方案中的 NHibernate 1.2

    我有一些基于 NHibernate 1 2 的项目 我想将它们添加到 NET 4 0 解决方案中 但我收到 AmbigeousMatchException 无论这些项目是针对2 0还是4 0框架 如果我将它们添加到 NET 3 5 解决方案
  • 将刻度转换为时间格式 (hh:mm:ss)

    我从网络服务器获取视频长度值作为刻度 我想以 hh mm ss 格式显示它 我怎样才能在 JavaScript 中做到这一点 假设刻度以秒为单位 如果不是 您可以先将其转换为秒 您可以通过查找时间跨度中的整分钟数和小时数 然后获取剩余的秒数
  • 我什么时候应该使用解析器?

    我在正则表达式中遇到了将代码划分为功能组件的问题 它们可能会破裂 也可能需要很长时间才能完成 这段经历提出了一个问题 我什么时候应该使用解析器 当您对以下内容感兴趣时 应该使用解析器文本的词汇或语义意义 当模式可以变化时 当您只是想了解时
  • Java正则表达式正向预测但仅匹配唯一字符?

    我正在尝试将字符串输入与以下条件进行匹配 第一个字符是unique小写英文字母 接下来的字符代表从 1500 到 2020 的当前年份 接下来的字符只能是 10 或 100 或 1000 最后一个字符是 0 到 9 之间的数字 我创建的正则
  • 在多个数据库上使用 ActiveRecord

    我正在编写一个工资系统 它将与现有系统集成 原始系统有一个主数据库 用于处理用户管理和一些全局配置 下面有多个结构相同的数据库 基本上每个数据库都是一个公司的工资数据库 所有这些都与主数据库绑定 因为它属于父数据库公司拥有多家子公司 每个子
  • 在 matplotlib 底图投影上绘制椭圆

    我正在尝试在底图投影上绘制椭圆 要画一个像多边形一样的圆 有tissot用于绘图的函数天梭的指标 http en wikipedia org wiki Tissot 27s indicatrix如下例所示 from mpl toolkits