Closed simonmr closed 8 years ago
Hey @simonmr,
That sounds excellent! I'm very happy to hear that someone is finally building a new real time plotting application for SuperDARN. Will this be open sourced at some point? I think we at SuperDARN Canada would be very interested in it
I'm not sure how you were planning on plotting the data in real time, but have you heard of mpld3 (https://mpld3.github.io/index.html)? If you were to use mpl3d, then you should simply be able to use davitpy to generate plots and have them displayed in the browser. They should be able to be updated in real time too.
I'll give you a quick example of how to make a plot in davitpy. I'll assume that you want to make a fan plot. Also, I'm assuming that you are grabbing code from the develop
branch. The code that does the fan plotting is contained in pydarn/plotting
. All of our plotting software assumes that you have a beamData
object populated with radar data (look at https://github.com/vtsuperdarn/davitpy/blob/develop/pydarn/sdio/radDataTypes.py#L759) so I would suggest that you populate a beamData object with the json data and then you should be able to simply use the pre-existing plotting routines.
Here's an example of how to make a fan plot in davitpy:
# Import what we need
import pydarn
from matplotlib import pyplot
from utils.coordUtils import coord_conv
import numpy
# Set some variables for plotting
coords = 'geo'
param = 'velocity'
scale=[-200,200]
gsct = True
velscl=1000.
# This code is just to open a data file and populate a beamData object with data
# Equivalently, one could populate the beamData object another way
myPtr = pydarn.sdio.radDataOpen(datetime(2014,7,14),'sas', fileType="fitacf")
myBeam = myPtr.readRec()
myBeam = myPtr.readRec()
myBeam = myPtr.readRec()
myBeam = myPtr.readRec()
myBeam = myPtr.readRec()
# Get site information
t=myBeam.time
site = pydarn.radar.site(radId=myBeam.stid,dt=t)
rad = pydarn.radar.network().getRadarById(myBeam.stid).code[0]
# Get site coordinates converted in to the coordinate system that we want to plot in
xlon, xlat = coord_conv(site.geolon, site.geolat, "geo", coords,
altitude=0., date_time=t)
# Get the radar Field of View (FOV)
myFov = pydarn.radar.radFov.fov(site=site, rsep=myBeam.prm.rsep,
ngates=myBeam.prm.nrang+1,
nbeams=site.maxbeam, coords=coords,
date_time=t)
# Get the coordinates for the full field of view of the radar so we can
# determine boundaries for the map we want to plot onto.
lonFull,latFull=[],[]
lonC,latC=[],[]
latFull.append(xlat)
lonFull.append(xlon)
latC.append(xlat)
lonC.append(xlon)
for b in range(0,site.maxbeam+1):
for k in range(0,myBeam.prm.nrang+1):
lonFull.append(myFov.lonFull[b][k])
latFull.append(myFov.latFull[b][k])
k=myBeam.prm.nrang
b=0
latC.append(myFov.latFull[b][k])
lonC.append(myFov.lonFull[b][k])
b=site.maxbeam
latC.append(myFov.latFull[b][k])
lonC.append(myFov.lonFull[b][k])
#Now that we have 3 points from the FOVs of the radars, calculate the lat,lon pair
#to center the map on. We can simply do this by converting from Spherical coords
#to Cartesian, taking the mean of each coordinate and then converting back
#to get lat_0 and lon_0
lonC,latC = (numpy.array(lonC)+360.)%360.0,numpy.array(latC)
xs=numpy.cos(numpy.deg2rad(latC))*numpy.cos(numpy.deg2rad(lonC))
ys=numpy.cos(numpy.deg2rad(latC))*numpy.sin(numpy.deg2rad(lonC))
zs=numpy.sin(numpy.deg2rad(latC))
xc=numpy.mean(xs)
yc=numpy.mean(ys)
zc=numpy.mean(zs)
lon_0=numpy.rad2deg(numpy.arctan2(yc,xc))
lat_0=numpy.rad2deg(numpy.arctan2(zc,numpy.sqrt(xc*xc+yc*yc)))
#Now do some stuff in map projection coords to get necessary width and height of map
#and also figure out the corners of the map
lonFull,latFull = (numpy.array(lonFull)+360.)%360.0,numpy.array(latFull)
tmpmap = utils.mapObj(coords=coords,projection='stere', width=10.0**3,
height=10.0**3, lat_0=lat_0, lon_0=lon_0,
datetime = t, draw=False)
x,y = tmpmap(lonFull,latFull)
minx = x.min()*1.05 #since we don't want the map to cut off labels or
miny = y.min()*1.05 #FOVs of the radar we should alter the extrema a bit.
maxx = x.max()*1.05
maxy = y.max()*1.05
width = (maxx-minx)
height = (maxy-miny)
llcrnrlon,llcrnrlat = tmpmap(minx,miny,inverse=True)
urcrnrlon,urcrnrlat = tmpmap(maxx,maxy,inverse=True)
# Now we can plot our data!
# Set up a figure to plot into
fig = pyplot.figure()
ax = fig.add_subplot(111)
#draw the actual map we want
myMap = utils.mapObj(coords=coords, projection='stere', lat_0=lat_0,
lon_0=lon_0, llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat,
urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat,
coastLineWidth=0.5, coastLineColor='k',
fillOceans='w',fillContinents='w', fillLakes='w',
datetime = t, ax=ax)
#Overlay the radar name/location and the FOV
pydarn.plotting.overlayRadar(myMap, codes=rad, dateTime=t)
pydarn.plotting.overlayFov(myMap, codes=rad, dateTime=t, fovObj=myFov)
#Overlay the fan plot data
cmap,norm,bounds = utils.plotUtils.genCmap(param,scale,colors='lasse',lowGray=False)
intensities, pcoll = pydarn.plotting.overlayFan(myBeam,myMap,fig,param,coords,gsct=gsct,
site=site,fov=myFov,
fill=True,cmap=cmap,norm=norm)
fig.show()
You should get a figure that looks something like this:
Some of this code is a bit messy and it would be nice to refactor it (on the to do list) but I stripped most of it out of the pydarn.plotting.fan.plotFan
function.
This sounds great. I can definitely make it open source once I have more of an idea exactly how I am going to implement this. I will look more into mpld3 that sounds really interesting. I'm currently using Tkinter, a built in GUI functionality in python, but it has a fair amount of lag time.
Thanks for all of the help
On Tue, Jun 16, 2015 at 3:43 PM, asreimer notifications@github.com wrote:
Hey @simonmr https://github.com/simonmr,
That sounds excellent! I'm very happy to hear that someone is finally building a new real time plotting application for SuperDARN. Will this be open sourced at some point? I think we at SuperDARN Canada would be very interested in it
I'm not sure how you were planning on plotting the data in real time, but have you heard of mpld3 (https://mpld3.github.io/index.html)? If you were to use mpl3d, then you should simply be able to use davitpy to generate plots and have them displayed in the browser. They should be able to be updated in real time too.
I'll give you a quick example of how to make a plot in davitpy. I'll assume that you want to make a fan plot. Also, I'm assuming that you are grabbing code from the develop branch. The code that does the fan plotting is contained in pydarn/plotting. All of our plotting software assumes that you have a beamData object populated with radar data (look at https://github.com/vtsuperdarn/davitpy/blob/develop/pydarn/sdio/radDataTypes.py#L759) so I would suggest that you populate a beamData object with the json data and then you should be able to simply use the pre-existing plotting routines.
Here's an example of how to make a fan plot in davitpy:
Import what we need
import pydarn from matplotlib import pyplot from utils.coordUtils import coord_conv import numpy
Set some variables for plotting
coords = 'geo' param = 'velocity' scale=[-200,200] gsct = True velscl=1000.
This code is just to open a data file and populate a beamData object with data
Equivalently, one could populate the beamData object another way
myPtr = pydarn.sdio.radDataOpen(datetime(2014,7,14),'sas', fileType="fitacf") myBeam = myPtr.readRec() myBeam = myPtr.readRec() myBeam = myPtr.readRec() myBeam = myPtr.readRec() myBeam = myPtr.readRec()
Get site information
t=myBeam.time site = pydarn.radar.site(radId=myBeam.stid,dt=t) rad = pydarn.radar.network().getRadarById(myBeam.stid).code[0]
Get site coordinates converted in to the coordinate system that we want to plot in
xlon, xlat = coord_conv(site.geolon, site.geolat, "geo", coords, altitude=0., date_time=t)
Get the radar Field of View (FOV)
myFov = pydarn.radar.radFov.fov(site=site, rsep=myBeam.prm.rsep, ngates=myBeam.prm.nrang+1, nbeams=site.maxbeam, coords=coords, date_time=t)
Get the coordinates for the full field of view of the radar so we can
determine boundaries for the map we want to plot onto.
lonFull,latFull=[],[] lonC,latC=[],[]
latFull.append(xlat) lonFull.append(xlon) latC.append(xlat) lonC.append(xlon)
for b in range(0,site.maxbeam+1): for k in range(0,myBeam.prm.nrang+1): lonFull.append(myFov.lonFull[b][k]) latFull.append(myFov.latFull[b][k])
k=myBeam.prm.nrang b=0 latC.append(myFov.latFull[b][k]) lonC.append(myFov.lonFull[b][k]) b=site.maxbeam latC.append(myFov.latFull[b][k]) lonC.append(myFov.lonFull[b][k])
Now that we have 3 points from the FOVs of the radars, calculate the lat,lon pair
to center the map on. We can simply do this by converting from Spherical coords
to Cartesian, taking the mean of each coordinate and then converting back
to get lat_0 and lon_0
lonC,latC = (numpy.array(lonC)+360.)%360.0,numpy.array(latC) xs=numpy.cos(numpy.deg2rad(latC))_numpy.cos(numpy.deg2rad(lonC)) ys=numpy.cos(numpy.deg2rad(latC))_numpy.sin(numpy.deg2rad(lonC)) zs=numpy.sin(numpy.deg2rad(latC)) xc=numpy.mean(xs) yc=numpy.mean(ys) zc=numpy.mean(zs) lon_0=numpy.rad2deg(numpy.arctan2(yc,xc)) lat_0=numpy.rad2deg(numpy.arctan2(zc,numpy.sqrt(xc_xc+yc_yc)))
Now do some stuff in map projection coords to get necessary width and height of map
and also figure out the corners of the map
lonFull,latFull = (numpy.array(lonFull)+360.)%360.0,numpy.array(latFull)
tmpmap = utils.mapObj(coords=coords,projection='stere', width=10.03, height=10.03, lat_0=lat_0, lon_0=lon_0, datetime = t, draw=False) x,y = tmpmap(lonFull,latFull) minx = x.min()_1.05 #since we don't want the map to cut off labels or miny = y.min()_1.05 #FOVs of the radar we should alter the extrema a bit. maxx = x.max()_1.05 maxy = y.max()_1.05 width = (maxx-minx) height = (maxy-miny) llcrnrlon,llcrnrlat = tmpmap(minx,miny,inverse=True) urcrnrlon,urcrnrlat = tmpmap(maxx,maxy,inverse=True)
Now we can plot our data!
Set up a figure to plot into
fig = pyplot.figure() ax = fig.add_subplot(111)
draw the actual map we want
myMap = utils.mapObj(coords=coords, projection='stere', lat_0=lat_0, lon_0=lon_0, llcrnrlon=llcrnrlon, llcrnrlat=llcrnrlat, urcrnrlon=urcrnrlon, urcrnrlat=urcrnrlat, coastLineWidth=0.5, coastLineColor='k', fillOceans='w',fillContinents='w', fillLakes='w', datetime = t, ax=ax)
Overlay the radar name/location and the FOV
pydarn.plotting.overlayRadar(myMap, codes=rad, dateTime=t) pydarn.plotting.overlayFov(myMap, codes=rad, dateTime=t, fovObj=myFov)
Overlay the fan plot data
cmap,norm,bounds = utils.plotUtils.genCmap(param,scale,colors='lasse',lowGray=False)
intensities, pcoll = pydarn.plotting.overlayFan(myBeam,myMap,fig,param,coords,gsct=gsct, site=site,fov=myFov, fill=True,cmap=cmap,norm=norm)
fig.show()
You should get a figure that looks something like this: [image: sas_example] https://cloud.githubusercontent.com/assets/4604819/8196949/025f3c9a-144f-11e5-920a-8b7e1f5f9134.png
Some of this code is a bit messy and it would be nice to refactor it (on the to do list) but I stripped most of it out of the pydarn.plotting.fan.plotFan function.
— Reply to this email directly or view it on GitHub https://github.com/vtsuperdarn/davitpy/issues/138#issuecomment-112603985 .
Hi, I'm new to davitpy but I've been working over here at University of Alaska to update our current real time radar plot from java to python. In the process of doing this I've wrapped the server code that runs on our radar sites so that it outputs json data instead of the current output. My task now is to, finally, convert the java code to python for the real time application linked on our website. To do this it looks like most of the plotting functionality can come from your code. I'm not sure how much code of yours I will use or exactly how to set up the code so it can process real time json data. At this time I'm in the initial test and break stage.
Any ideas or advice? Michelle