Posts tagged with 'Weather'
3 years ago

Weather data + chart in C# using OpenWeatherMap or Yahoo API


If you need weather forecast data, OpenWeatherMap and Yahoo have free APIs to get you covered.

Here I will show how grab this data in C# and, just for fun, how to plot the temperature forecast over a line graph using OxyPlot.

Yahoo API request URL

Yahoo gives you a 7 days forecast in a daily fashion.

Simply access the following URL which contains YQL query to fetch data from the weather.forecast table and return it in JSON format (or XML if you want): * from weather.forecast where woeid in (select woeid from geo.places(1) where text='caxias do sul') and u='c'&format=json

This sample URL returns forecast to my city, Caxias do Sul / Brazil.

Notice the u='c' which makes it returns temperatures in Celsius.

OpenWeatherMap API request URL

OpenWeatherMap free alternative offers a 5 day / 3 hour forecast.

First you need to register and get an API key to query their REST API.

Then you need the ID of the city you want the forecast:

  1. Go to
  2. Search your city
  3. Click its name
  4. In the resulting page URL, like, copy the numberic part, so 3466537 in this example

GET the following URL (replacing CITYID and APPID with the city ID and API key, respectively):{CITYID}&APPID={APPID}&units=metric

Note that I want temperature values in Celsius degrees, which means to use the metric system, hence the units=metric parameter.

Graph in C# / OxyPlot

The following graph is the live 5 day / 3 hour temperature forecast returned by OpenWeatherMap for my city:

Behind this image, I am using OxyPlot to generate a PNG image from the JSON data, and returning it through the /Weather/CxsForecastPlot URL.

Code behind the ASP.NET MVC action for this URL:

// GET: CxsForecastPlot
public ActionResult CxsForecastPlot()
	PlotModel model = new PlotModel()
		PlotAreaBorderColor = OxyColor.Parse("#BBBDBE"),
		TextColor = OxyColor.Parse("#50606F"),

	var temperatureAxis = new LinearAxis()
		Minimum = 0,
		Maximum = 50,
		Title = "Temperature CÂș",
		MajorGridlineThickness = 1,
		MajorGridlineStyle = LineStyle.Solid,
		MajorGridlineColor = OxyColor.Parse("#E9ECEF"),
		CropGridlines = true,
		TickStyle = TickStyle.None

	var dateAxis = new DateTimeAxis()
		StringFormat = "MMM dd",
		TickStyle = TickStyle.None

	LineSeries serie = new LineSeries()
		MarkerType = MarkerType.Circle,
		MarkerSize = 4,
		MarkerStrokeThickness = 1,
		MarkerStroke = OxyColors.Black,
		MarkerFill = OxyColors.White,
		StrokeThickness = 3,
		ItemsSource = GetForecastData().Select(e => new DataPoint(DateTimeAxis.ToDouble(e.dt), e.temperatureC)).ToList()

	using(var ms = new MemoryStream())
		var export = new PngExporter() { Width = 900 };
		export.Export(model, ms);
		return new ImageResult(ms.ToArray(), "image/png");

class WeatherData
	public DateTime dt;
	public double temperatureC;
	public double humidity;

private List<WeatherData> GetForecastData()
	List<WeatherData> result = new List<WeatherData>();

	// GET the data from REST API
	// HttpClient need Microsoft.Net.Http NuGeT
	using(var client = new HttpClient())
		HttpResponseMessage response = client.GetAsync($"{CITY_ID}&APPID={OWM_APPID}&units=metric").Result;

		string json = Encoding.UTF8.GetString(response.Content.ReadAsByteArrayAsync().Result);
		dynamic dynjson = JSON.DeserializeObject(json);
		foreach(var item in dynjson.list)
			result.Add(new WeatherData
				dt = Utils.FromUnixTime((long) item.dt),
				temperatureC = (double) item.main.temp,
				humidity = (double) item.main.humidity

	return result;

public class ImageResult : ActionResult
	public ImageResult(byte[] image, string contentType)
		if(image == null)
			throw new ArgumentNullException("image");
		if(contentType == null)
			throw new ArgumentNullException("contentType");

		this.Buffer = image;
		this.ContentType = contentType;

	public byte[] Buffer { get; private set; }
	public string ContentType { get; private set; }

	public override void ExecuteResult(ControllerContext context)
		if(context == null)
			throw new ArgumentNullException("context");

		HttpResponseBase response = context.HttpContext.Response;

		response.ContentType = this.ContentType;
		response.OutputStream.Write(Buffer, 0, Buffer.Length);

public static class Utils
	public static DateTime FromUnixTime(this long unixTime)
		var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
		return epoch.AddSeconds(unixTime);

Make sure to install Newtonsoft.Json and OxyPlot.WindowsForms NuGeTs. Each service has its own JSON format.

For easily navigating the returned JSON data, notice that I am using C# dynamic binding feature.