Wolfram Language Applications for Astro Visualization

By Jeff Bryant, Wolfram|Alpha, LLC

Join the Conversation #AustralasiaWTC2026

History of Astronomy in Wolfram Language

• AstronomicalData added in v6 (2007)

• EntityValue added in v10 (2014)

• AstroPosition/AstroGraphics/etc added in v13.2 (2022)

• SolarEclipse overhauled in 14.0 (2024)

• OrbitalElements added in v15 (2026)

EntityValue

Unlike AstronomicalData which tried to represent objects using simple string identifiers, the entity framework, introduced in version 10, also encodes the data domain. If you know the name and type of the object you are interested in, the Entity can be resolved using Interpreter:

star=Interpreter["Star"]["HD 148478"]

Once you have the entity, you can query for its properties:

EntityValue[star,"Dataset"]

Not all properties are quantitative (the following uses the operator form for EntityValue):

(Entity["Mars", Entity["Planet","Mars"], "Entity[\"Planet\", \"Mars\"]", "planet"])["TexturedSurface"]

In addition, entities can also be arguments to other WL functions:

AstroPosition[star]

ResourceFunction["HertzsprungRussellDiagram"][star,ImageSize->400]

AstroGraphics

Returning to the origins of astronomy, AstroGraphics lets us look at what’s in the sky (the whole current sky from your current location by default):

AstroGraphics[]

For additional style, a more photorealistic sky can be included showing the Milky Way in the background:

AstroGraphics[AstroBackground->"GalacticSky"]

But we don’t have to look at the whole sky, we can zoom into various parts of the sky to see more details.

AstroGraphics[(Entity["Sextans", Entity["Constellation","Sextans"], "Entity[\"Constellation\", \"Sextans\"]", "constellation"]),AstroReferenceFrame->"Ecliptic",AstroBackground->AstroStyling[{"BlackSky","ShowConstellations"->{(Entity["Sextans", Entity["Constellation","Sextans"], "Entity[\"Constellation\", \"Sextans\"]", "constellation"])}, "ShowConstellationIllustrations" -> True}]]

AstroGraphics can also be used to show the sky as it would appear from a specified location and date/time:

AstroGraphics[AstroReferenceFrame->{"Horizon",DateObject[{2026,6,5,22,0,0},TimeZone->10],(Entity["Macquarie University", Entity["University","MacquarieUniversity::565m7"], "Entity[\"University\", \"MacquarieUniversity::565m7\"]", "university"])},AstroBackground->"GalacticSky"]

SolarEclipse

Overhauled in 14.0, SolarEclipse allows you to find a solar eclipse relative to an input date. In 15.0, FindSolarEclipse is introduced which finds an eclipse relative to an input location.

loc=(Entity["Sydney", Entity["City",{"Sydney","NewSouthWales","Australia"}], "Entity[\"City\", {\"Sydney\", \"NewSouthWales\", \"Australia\"}]", "city"]);

The resulting date is the date of maximum eclipse, globally:

eclipse=FindSolarEclipse[loc,EclipseType->"Total"]

Once you have the eclipse of interest, you can use AstroGraphics to see what the eclipse will look like at that location and time (notice the Moon isn’t blocking the Sun):

AstroGraphics[AstroCenter->(Entity["Sun", Entity["Star","Sun"], "Entity[\"Star\", \"Sun\"]", "star"]),AstroReferenceFrame->{eclipse,loc},AstroRange->Quantity[1, "AngularDegrees"]]

You can also get a geographic map showing the path of the eclipse:

SolarEclipse[eclipse,"EclipseMap"]

But we can compute the location and date/time of maximum eclipse:

maxloc=SolarEclipse[eclipse,"MaximumEclipsePosition"]

maxtime=SolarEclipse[eclipse,"MaximumEclipseDate"]

Offsetting the time by a10 minutes, we can see the eclipse approaching totality at the global maximum location:

AstroGraphics[AstroCenter->(Entity["Sun", Entity["Star","Sun"], "Entity[\"Star\", \"Sun\"]", "star"]),AstroReferenceFrame->{maxtime-Quantity[10,"Minutes"],maxloc},AstroRange->Quantity[1, "AngularDegrees"]]

Returning to the original location of Sydney, we can find the maximum time there:

sydneytime=SolarEclipse[eclipse,{"LocalMaximumEclipseDate",loc}]

Then, as before, offset this by 10 minutes to see totality approaching:

AstroGraphics[AstroCenter->(Entity["Sun", Entity["Star","Sun"], "Entity[\"Star\", \"Sun\"]", "star"]),AstroReferenceFrame->{sydneytime-Quantity[10,"Minutes"],loc},AstroRange->Quantity[1, "AngularDegrees"]]

OrbitalElements

In version 15, OrbitalElements is introduced. It computes a complete set of orbital elements and derived orbit properties given an object or set of basic elements:

Planets

OrbitalElements[(Entity["Mars", Entity["Planet","Mars"], "Entity[\"Planet\", \"Mars\"]", "planet"])]

OrbitalElements[(EntityClass["planets", EntityClass["Planet",All], "EntityClass[\"Planet\", All]", "planets"])]//Tabular

Moons

orbs=OrbitalElements[(EntityClass["moons of Jupiter", EntityClass["PlanetaryMoon","JupiterMoon"], "EntityClass[\"PlanetaryMoon\", \"JupiterMoon\"]", "planetary moons"]),"OrbitLine"];

Graphics3D[{orbs}]

Deep Space Probes

probe=(Entity["Voyager 2", Entity["DeepSpaceProbe","Voyager2"], "Entity[\"DeepSpaceProbe\", \"Voyager2\"]", "deep space probe"]);

orbit=OrbitalElements[%,"OrbitLine"];

probe["LaunchDate"]

trueorbit=Line@Table[AstroPosition[probe,{"EclipticICRS",d,"Sun"},"Cartesian"]["Data"],{d,%+(Quantity[1, "day", day, "Days"]),Now,(Quantity[10, "days", days, "Days"])}];

pos=OrbitalElements[probe,"PositionVector",UnitSystem->None]

Graphics3D[{AbsoluteThickness[1],{Gray,EntityValue["Planet","OrbitPath"]},AbsoluteThickness[2],Gray,orbit,StandardRed,PointSize[Large],Point[pos],trueorbit},Boxed->False,ViewPoint->{-2.45,-1.6,1.8},PlotRange->45,Method->{"ShrinkWrap" -> True}]

GeoGraphics - GeoModel

Astronomy isn’t limited to the skies, but also includes geography on other solar system bodies:

GeoGraphics[GeoModel->"Mars",GeoCenter->GeoPosition[{35,180}],GeoProjection->"Orthographic",ImageSize->400,Background->None,GeoGridLines->Automatic,GeoGridLinesStyle->Directive[AbsoluteThickness[1],GrayLevel[1,.5]]]

GeoGraphics[GeoModel->"Ceres",GeoCenter->GeoPosition[{35,180}],GeoProjection->"Orthographic",ImageSize->400,Background->None,GeoGridLines->Automatic,GeoGridLinesStyle->Directive[AbsoluteThickness[1],GrayLevel[1,.5]]]

Version 15 also extends NightHemisphere (and DayHemisphere) to solar system bodies other than Earth. Combined with AstroSubpoint, the phases of planets can be seen from the Earth (or other solar system bodies) on a given date:

With[{date=Now},
GeoGraphics[{GeoStyling[Opacity[1]],NightHemisphere[date]},GeoModel->"Venus",GeoCenter->AstroSubpoint["Earth",{"Venus",date}],GeoProjection->"Orthographic",ImageSize->400,Background->Black,GeoGridLines->Automatic,GeoGridLinesStyle->Directive[AbsoluteThickness[1],GrayLevel[1,.35]]]]

GeoGraphics - Solar System Features

Its not just the global map of other solar system bodies, but individual features that can be mapped as well:

With[{feature=(Entity["Copernicus crater", Entity["SolarSystemFeature","CopernicusMoon"], "Entity[\"SolarSystemFeature\", \"CopernicusMoon\"]", "solar system feature"])},GeoGraphics[{feature},GeoRange->feature["Size"]/2,GeoProjection->"Orthographic"]]

With[{feature=(Entity["Olympus Mons", Entity["SolarSystemFeature","OlympusMonsMars"], "Entity[\"SolarSystemFeature\", \"OlympusMonsMars\"]", "solar system feature"])},GeoGraphics[{feature},GeoRange->feature["Size"]/2,GeoProjection->"Orthographic"]]

With[{feature=(Entity["Verona Rupes", Entity["SolarSystemFeature","VeronaRupesMiranda"], "Entity[\"SolarSystemFeature\", \"VeronaRupesMiranda\"]", "solar system feature"])},GeoGraphics[{feature},GeoRange->Quantity[100,"Miles"],GeoProjection->"Orthographic",GeoGridLines->Automatic]]

SolarImage/SolarVideo

Solar activity is monitored by a number of instruments and the resulting images are available via an API provided by helioviewer.gov. Using the Wolfram ResourceFunction SolarImage, you can get access to the latest solar images in many wavelengths. SolarVideo provides easy ways to create videos. Imagery is available for current and historical dates/times.

ResourceFunction["SolarImage"][]

ResourceFunction["SolarImage"][9]

ResourceFunction["SolarImage"][13]

WFR:

Community post:
https://community.wolfram.com/groups/-/m/t/3106012
https://community.wolfram.com/groups/-/m/t/3573731

SpaceWeatherData

NASA provides repositories on various servers for space weather measurements. Sunspot counts, Solar X-rays, Solar wind and many other measurements are available and accessible using another Wolfram Function Repository item, SpaceWeatherData:

annualsunspotts=ResourceFunction["SpaceWeatherData"][{DateObject[{1611}],DateObject[{2026}]},"YearlySunspotNumber"]

DateListPlot[annualsunspotts,FrameLabel->{None,Automatic},Epilog->{Orange,Opacity[.2],Rectangle[{AbsoluteTime[{1645}],0},{AbsoluteTime[{1715}],300}],Green,Rectangle[{AbsoluteTime[{1790}],0},{AbsoluteTime[{1830}],300}],Purple,Rectangle[{AbsoluteTime[{1914}],0},{AbsoluteTime[{2000}],300}]}]

monthlysunspotts=ResourceFunction["SpaceWeatherData"][{DateObject[{1995}],DateObject[{2027}]},"MonthlySunspotNumber"]

DateListPlot[monthlysunspotts,FrameLabel->{None,Automatic}]

xraylongts=ResourceFunction["SpaceWeatherData"][DateObject[{2026,6,1}],"LongSolarXRayFlux"]

DateListLogPlot[xraylongts,FrameLabel->{None,Automatic}]

https://resources.wolframcloud.com/FunctionRepository/resources/SpaceWeatherData/

DESI/NoirLabs

The Dark Energy Spectroscopic Instrument is an ongoing effort to measure the expansion of the universe by mapping many galaxies. The final dataset is planned to involve 47 millions galaxies, but the data release 1 (DR1) is publically available and contains 13+ million galaxies. An API provides access to DR1 if you are patient enought to download all of the data:

chunkSize=100000;

maxChunk=131;

AbsoluteTiming[allData=Flatten[Monitor[Table[
resp=URLRead[HTTPRequest["https://datalab.noirlab.edu/tap/sync",
<|"Method"->"GET",
"Body"->{"REQUEST"->"doQuery",
"LANG"->"ADQL",
"FORMAT"->"csv",
"QUERY"->"SELECT p.ra, p.dec, z.z
                  FROM desi_dr1.zpix AS z
                  JOIN desi_dr1.photometry AS p ON z.targetid = p.targetid
                  WHERE z.zcat_primary = 't'
                    AND z.zwarn = 0
                    AND z.spectype = 'GALAXY'
                  LIMIT "<>ToString[chunkSize]<>" OFFSET "<>ToString[i*chunkSize]}|>
]
];
Rest[ImportString[resp["Body"],"CSV"]],(*drop header after first chunk*){i,0,maxChunk}],Progress`ProgressPanel[Grid[{{ProgressIndicator[i,{0,maxChunk}]},{Row[{"Chunk ",i," out of 131"}]}},Alignment->Left]]],1];]

Notice this took over 2 hours to download the data from the source:

UnitConvert[Quantity[7537.6615107`,"Seconds"],MixedUnit[{"Hours","Minutes","Seconds"}]]

Dump the results to a package file.

allData>>"C:\\Users\\jeffb\\Desktop\\DESI-GalaxiesDR1\\DESI-GalaxiesDR1.m"

Once the data is initially retrieved, you don’t have to use the API to get the data again, simply read the package file in a fresh session and make sure to convert it to use a packed array which shrinks the matrix of triples from 1.5 GB down to 317 MB.

allData=Developer`ToPackedArray[Get["C:\\Users\\jeffb\\Desktop\\DESI-GalaxiesDR1\\DESI-GalaxiesDR1.m"]];

The data encodes distance via the redshift value (3rd element of each triple):

redshiftrange=MinMax[allData[[All,3]]]

Declination is the 2nd element of each triple:

dec=allData[[All,2]];

decminmax=MinMax[dec]

Utility function to convert spherical coordinates to Cartesian:

sphericalToCartesian[{ra_,dec_,z_}]:=AstroPosition[AstroPosition[{ra,dec,z},"ICRS","Spherical"],"ICRS","Cartesian"]["Data"]

Point Cloud

Due to the size of the data and difficulty of viewing so many points, its useful to look at a subset. The following selects only those triples with a redshift of 0.1 or lower and also constructs a list of colors for each point , coded based on the declination angle. This color can help to provide a sense of depth in a static rendering so that points in the background are colored differently from those in the front.

{colors,pts}={#[[1]],Developer`ToPackedArray[#[[2]]]}&@Transpose[{Blend[{Green,RGBColor[1,.9,.7],RGBColor[1,.9,.2]},#]&@Rescale[Abs[#[[2]]],{0,decminmax[[2]]}],sphericalToCartesian[#]}&/@Select[allData,#[[3]]<=.1&]];

Dimensions[pts]

To optimize rendering, a single Point primitive is used and the colors are applied via the VertexColors option to that point. In addition, VertexNormals are specified (identical to the points themselves) to be radial so that lighting effects are applicable and points near the camera are brighter than those further away.

ptcloud=Graphics3D[{White,PointSize[0],Opacity[1],Point[pts,VertexNormals->pts,VertexColors->colors]},Background->Black,ImageSize->600,Lighting->{AmbientLight[GrayLevel[.1]],DirectionalLight[White,ImageScaled[{0,0,1}]]},SphericalRegion->True,ViewAngle->Pi/6,Boxed->False,ViewPoint->Top]

Volumetric Data

Another possibility is to bin the data points into voxels of 512x512x512 in size

(*Step 2:bounding box*)
{xmin,xmax}=MinMax[pts[[All,1]]];
{ymin,ymax}=MinMax[pts[[All,2]]];
{zmin,zmax}=MinMax[pts[[All,3]]];

n=512;
grid=BinCounts[pts,{xmin,xmax,(xmax-xmin)/n},{ymin,ymax,(ymax-ymin)/n},{zmin,zmax,(zmax-zmin)/n}];
(*takes~10-20 sec*)

Image3D with a color function then color codes based on density. Note that the data is divided by 5 to reduce the opacity overall. The sparse data on the outskirst then becomes nearly invisible allowing the denser inner regions to be more visible.

img3d=Image3D[grid/5,ImageSize->600,SphericalRegion->True,ViewAngle->Pi/6,Background->Black,ColorFunction->"SunsetColorsOpacity",ViewPoint->Right,ViewVertical->{0,1,0}]

References

Reference pages:
AstroGraphics
GeoGraphics

Wolfram Core Areas: Astronomy:
https://www.wolfram.com/language/core-areas/astronomy/

Wolfram Function Repository TelescopeView3D:
https://resources.wolframcloud.com/FunctionRepository/resources/TelescopeView3D

Wolfram Function Repository:Astronomy:
https://resources.wolframcloud.com/FunctionRepository/category/astronomical-computation-data?sortBy=Name

Wolfram Community: Astronomy
https://community.wolfram.com/content?curTag=astronomy

JPL HORIZONS WFR/API:
https://resources.wolframcloud.com/FunctionRepository/resources/HorizonsEphemerisData/

Helioviewer API:
https://api.helioviewer.org/docs/v2/