使用 matplotlib 创建全天空投影的奇怪(坏?)行为

发布于 2024-12-03 10:22:30 字数 2134 浏览 1 评论 0原文

我正在尝试制作一个密度“全天空”图,该图在 RA 中完整(即 0 到 360 度),但在 DEC 中不完整(假设从 -45 到 90 度)。如果我在没有任何投影的情况下绘制它,那就可以了,但是当我尝试使用“mollweide”投影进行绘制时,我没有恢复输入,但如果我对代码做了一些更改,我确实会恢复预期的行为(但是,我正如您将在示例中看到的那样,对于此更改没有连贯的解释)。

让我们看一个独立的示例,其输出更清晰:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.backends.backend_agg
from math import pi

#array between 0 and 360 deg
RA = np.random.random(10000)*360
#array between -45 and 90 degrees. By construction!
DEC= np.random.random(10000)*135-45

fig = plt.Figure((10, 4.5))
ax = fig.add_subplot(111,projection='mollweide')
ax.grid(True)
ax.set_xlabel('RA')
ax.set_ylabel('DEC')

ax.set_xticklabels(np.arange(30,331,30))
hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-90,90],[0,360]])
#TO RECOVER THE EXPECTED BEHAVIOUR, I HAVE TO CHANGE -90 FOR -80 IN THE PREVIOUS LINE:
#hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-80,90],[0,360]])
#I DO NOT WHY!

extent = (-pi,pi,-pi/2.,pi/2.)
image = ax.imshow(hist,extent=extent,clip_on=False,aspect=0.5,origin='lower')

cb = fig.colorbar(image, orientation='horizontal')
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

fig.canvas.print_figure("image1.png")

输出图像是: [由于我是新来的,所以我不被允许发布图片,所以我会发布一个链接,如果不起作用,请给我写一封电子邮件,我可以与图片共享一个 Dropbox 文件夹;)]

我得到的输出图像

你可以清楚地看到 RA 是好的,所以它的范围在 0 到 360 之间,但是DEC 范围从 -35 到 90,而不是 -45 到 90。到目前为止,我不明白为什么我缺少 10 度。

但是,如果我在代码中做一点更改,替换行

hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-90,90 ],[0,360]]

hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-80,90],[0,360]]

我得到了我认为应该得到的,这是这个图:

< a href="http://oi53.tinypic.com/2yl1nch.jpg" rel="nofollow">输出图像 2

[同样,如果链接不起作用,让我知道,我可以与您共享一个 Dropbox 文件夹]

,其中 DEC 现在的范围从 -45 到 90,正如预期的那样,因为我以这种方式创建了 DEC,

但是将 -90 更改为 -80 没有意义(我认为)。 所以可能我做错了一些我现在无法注意到的错误,或者我误解了代码中的某些内容,或者 matplotlib 中存在一个奇怪的错误?

请任何帮助/提示/更正将不胜感激

Eduardo

I am trying to make a density "all-sky" plot which is complete in RA (i.e 0 to 360 deg) but incomplete in DEC (let's say from -45 to 90 deg). If I plot this without any projection it is ok, but when I try to plot using the 'mollweide' projection I am not recovering the input, but if I do a little change in the code I do recover the expected behavior (however, I don't have a coherent explanation for this change as you'll see in the example).

Let's see a self-contained example with its outputs to be clearer:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.backends.backend_agg
from math import pi

#array between 0 and 360 deg
RA = np.random.random(10000)*360
#array between -45 and 90 degrees. By construction!
DEC= np.random.random(10000)*135-45

fig = plt.Figure((10, 4.5))
ax = fig.add_subplot(111,projection='mollweide')
ax.grid(True)
ax.set_xlabel('RA')
ax.set_ylabel('DEC')

ax.set_xticklabels(np.arange(30,331,30))
hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-90,90],[0,360]])
#TO RECOVER THE EXPECTED BEHAVIOUR, I HAVE TO CHANGE -90 FOR -80 IN THE PREVIOUS LINE:
#hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-80,90],[0,360]])
#I DO NOT WHY!

extent = (-pi,pi,-pi/2.,pi/2.)
image = ax.imshow(hist,extent=extent,clip_on=False,aspect=0.5,origin='lower')

cb = fig.colorbar(image, orientation='horizontal')
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

fig.canvas.print_figure("image1.png")

And the output image is:
[As I am new here I am not allowed to post images, so I will post a link, if it does not work, please write me an email and I can share a Dropbox folder with the images ;)]

Output Image that I am getting

Where you can see clearly that the RA is OK so it ranges between 0 and 360, BUT the DEC ranges from -35 to 90 instead of -45 to 90. So far I do not understand why I am missing 10 deg.

However, if I do a little change in the code, replacing the line

hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-90,90],[0,360]]

for

hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[90,180],range=[[-80,90],[0,360]]

I get what I think I should get, which is this plot:

Output Image 2

[Again, if the link does not work, let me know and I can share a Dropbox folder with you]

where DEC now ranges from -45 to 90 as expected because I created DEC in that way.

However the change of -90 for -80 doesn't make sense (I think).
So probably I am doing something wrong that I can't notice now, or I am misunderstanding something in the code or there is a curious bug in matplotlib??

Please any help/hint/correction would be greatly appreciate it

Eduardo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

软糖 2024-12-10 10:22:30

如果你不介意依赖外部包,你可以使用healpy来做到这一点,它为Healpix天空像素化提供了Mollweide投影:

https://github.com/healpy/healpy

在此处查看与您的脚本类似的示例:

https://gist.github.com/1215159

有关healpix的更多信息:

http://healpix.jpl.nasa.gov/html/intro.htm

输出图像:
Mollview 中的命中图示例

if you don't mind depending on an external package, you could do this with healpy, that provides a Mollweide projection for the Healpix sky pixellization:

https://github.com/healpy/healpy

See an example similar to your script here:

https://gist.github.com/1215159

More info about healpix:

http://healpix.jpl.nasa.gov/html/intro.htm

Ouput image:
Example hitmap in Mollview

七七 2024-12-10 10:22:30

如果这对其他人有用,这是我的代码的“更正版本”,它给出了这个 图像作为输出。主要的变化是使用 pcolormesh 而不是 imshow (正如 @Joe 建议的那样):

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.backends.backend_agg

#array between 0 and 360 deg
#CAVEAT: it seems that is needed an array from -180 to 180, so is just a
#shift in the coordinates
RA = np.random.random(10000)*360-180
#array between -45 and 90 degrees
DEC= np.random.random(10000)*135-45

fig = plt.Figure((10, 5))
ax = fig.add_subplot(111,projection='mollweide')

ax.set_xlabel('RA')
ax.set_ylabel('DEC')
ax.set_xticklabels(np.arange(30,331,30))

hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[60,40],range=[[-90,90],[-180,180]])

X,Y = np.meshgrid(np.radians(yedges),np.radians(xedges))

image = ax.pcolormesh(X,Y,hist)
ax.grid(True)
cb = fig.colorbar(image, orientation='horizontal')
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
fig.canvas.print_figure("image4.png")

If this is useful for someone else, this is the "corrected version" of my code, which gives as output this image. The main change is to use pcolormesh instead of imshow (as @Joe suggested):

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.backends.backend_agg

#array between 0 and 360 deg
#CAVEAT: it seems that is needed an array from -180 to 180, so is just a
#shift in the coordinates
RA = np.random.random(10000)*360-180
#array between -45 and 90 degrees
DEC= np.random.random(10000)*135-45

fig = plt.Figure((10, 5))
ax = fig.add_subplot(111,projection='mollweide')

ax.set_xlabel('RA')
ax.set_ylabel('DEC')
ax.set_xticklabels(np.arange(30,331,30))

hist,xedges,yedges = np.histogram2d(DEC,RA,bins=[60,40],range=[[-90,90],[-180,180]])

X,Y = np.meshgrid(np.radians(yedges),np.radians(xedges))

image = ax.pcolormesh(X,Y,hist)
ax.grid(True)
cb = fig.colorbar(image, orientation='horizontal')
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
fig.canvas.print_figure("image4.png")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文