Giter Club home page Giter Club logo

csharp-data-visualization's Introduction

C# Data Visualization

  • This repository is a collection of C# code examples that draw graphics to display data

  • Additional resources are available at https://swharden.com/csdv/

Graphics Simulations

These examples were created for the C# Data Visualization Website and mostly involve creating rendering-library-agnostic models of complex systems, then developing rendering systems that can display the models.

Project Screenshot
Mystify Your Mind with C# - The classic screensaver implemented using both OpenGL and System.Drawing. See C# Data Visualization Website for details.
Game of Life in C# - Conway's Game of Life is a zero-player video game that uses a few basic rules to determine if cells live or die based on the density of their neighbors. In this project we create Life using C# and System.Drawing. See C# Data Visualization Website for details.
Boids in C# - This project implements the Boids flocking algorithm in C# to create an interesting procedural animation of bird-drones (boids) scurrying about the screen. See C# Data Visualization Website for details.
Boids in C# with SkiaSharp - This project is an extension of the original boids project that uses an abstracted rendering system supporting SkiaSharp and OpenGL for hardware-accelerated rendering. See C# Data Visualization Website for details.
Spline Interpolation with C# - This project demonstrates how to create a smooth curve from a rough set of X/Y points using cubic spline interpolation. The interpolation code used here is in a .NET Standard 2.0 library, and the interactive GUI is a WinForms App using ScottPlot.

Drawing with Different Graphics Technologies

Drawing Graphics from Scratch

Description Screenshot
Create a bitmap by editing bytes in memory and save the resulting image to disk without using any image manipulation library dependency

Drawing Graphics with Maui.Graphics

These examples use Microsoft.Maui.Graphics package to provide cross-platform drawing in .NET Core and .NET Framework applications.

Description Screenshot
Draw with Maui.Graphics in Windows Forms, WPF, and MAUI apps - This project encapsulates drawing logic in a .NET Standard library using Maui.Graphics (with no dependency on System.Drawing). This common library is then referenced by separate Maui, Windows Forms, WPF, and console apps to display images and animations.
Audio Level Monitor with Maui.Graphics - This project uses NAudio to continuously sample the default microphone device, calculate the maximum intensity, and display it in a Windows Forms application using the SkiaSharp OpenGL control.
Microphone FFT Display with Maui.Graphics - This project uses NAudio to continuously sample the default microphone device, calculate the Fast fourier transform (FFT), and display the result in a Windows Forms application using the SkiaSharp OpenGL control.
Life with Maui.Graphics - This implementation of Conway's Game of Life uses an isolated class library to encapsulate the game board's logic and rendering methods, and a separate Windows Forms application to provide the interactive GUI to display the board using SkiaSharp and OpenGL.
Graphics Model Viewer - This project has a .NET Standard library of graphics models containing simulation logic and rendering methods, and multiple GUI applications (Windows Forms, WPF, etc.) that display them using different rendering technologies.
Compare Maui.Graphics Skia rendering performance in Windows Forms with and without OpenGL - A test pattern of 10,000 anti-aliased semi-transparent lines is used to evaluate framerate performance of the skControl compared to the skglControl. On my system the standard control is over 6 times slower than the OpenGL control (3 Hz vs 20 Hz).

Drawing in WPF Applications

Description Screenshot
Drawing Lines with WPF is a minimal-case example to demonstrate how to add primitive shapes to a canvas in a WPF application

Drawing with SkiaSharp and OpenGL

System.Drawing uses the GDI+ backend to draw on the screen. It is convenient because it is been around forever and is easily supported by .NET, but it does not perform well in parallel environments or with large bitmaps (e.g., full screen). See this page for a thorough description of its limitations. Most examples on this page use GDI+ to create images. For a long time System.Drawing was limited to .NET Framework applications, but in 2018 the System.Drawing.Common package brought System.Drawing support to .NET Core.

SkiaSharp is a cross-platform .NET API for drawing with Skia, an open-source 2D drawing library developed by Google. SkiaSharp has an OpenGL control which allows hardware-accelerated rendering using OpenGL out of the box without requiring any OpenGL knowledge.

Description Screenshot
Drawing with SkiaSharp and OpenGL - This program demonstrates how to vastly outperform GDI+ (System.Drawing) when drawing thousands of semi-transparent lines at full-screen window sizes.

Drawing in Blazor with WebAssembly

Client-side Blazor lets graphics models written in C# compile-down to WebAssembly that can run in the browser on a static website. No special hosting is required! At the time of writing client-side Blazor is on the bleeding edge of development, and performance is mediocre. For intense rendering jobs in the browser JavaScript is still required, but for simple tasks you can define graphics models in C# and render them with a HTML Canvas API without ever learning C#

Description Screenshot
Animation in the Browser with Blazor WebAssembly and HTML Canvas (see blog post and live demo) - This program demonstrates how to write a graphics model in C# and render it using the Blazor.Extensions.Canvas to draw on a HTML canvas. See the blog post for details
Blazor Boids in your Browser (see blog post and live demo) - demonstrates how to use a C# graphics model with .NET code managing business logic and a JavaScript render method which uses the high speed HTML5 canvas to do the drawing.
Mystify your Browser with Blazor (see blog post and live demo) The classic Windows 3 screensaver now runs in the browser! The graphics model is in C# and uses Blazor bindings to control various settings. Blazor tells JavaScript what to render (using JSON) and JavaScript draws colored lines on a HTML canvas.
Google Charts in Blazor (see blog post and live demo) shows how to generate data in C# and display it interactively in the browser using Google Charts

Visualizing Audio in C#

Description Screenshot
Audio Monitor - Demonstrates how to connect to an audio device using NAudio and plot the levels in real time using ScottPlot
FFT Monitor - Extends the audio monitor project by using FftSharp to calculate the frequency component of live microphone audio and display the result using ScottPlot
Plotting Audio Amplitude - This example uses NAudio to access the sound card, calculates the amplitude of short recordings, then graphs them continuously in real time with ScottPlot. This project is a good place to get started to see how to interface audio input devices.
Plotting Audio Values - This example uses NAudio to access the sound card and plots raw PCM values with ScottPlot. These graphs contain tens of thousands of data points, but remain fully interactive even as they are being updated in real time.
Plotting Audio FFT - This example continuously plots the frequency component of an audio input device. The NAudio library is used to acquire the audio data and process the FFT and ScottPlot is used for the plotting.
Microphone Level Monitor - This console application uses NAudio to continuously monitor the microphone and display audio levels by printing characters to the screen. Examples are provided for mono and stereo audio inputs.

Independent Projects

Some code examples started in this repository and have matured into their own projects

Project Screenshot
ScottPlot is an interactive plotting library for .NET. If you're just looking for an easy way to interactively display some data on a graph using C#, ScottPlot might be for you!
Spectrogram is a simple spectrogram library for .NET. Specrogram converts signals (typically audio) into the frequency-domain and makes it easy to display spectrograms as 2D images. Spectrogram is fast enough to display the audio spectrum in real time.
Sound Card ECG uses scottplot to interactively display the soundcard signal in real time
HHSharp is an interactive Hodgkin-Huxley neuron simulator

Older Projects

⚠️ Code quality warning: This section contains projects and notes I created when I was first learning how to draw graphics with C#. They work, but likely have poor code quality. I share them here in case someone may find them useful, but they should certainly not be deeply studied or accepted as best practice.

Description Screenshot
Is a point inside a rotated rectangle? This Windows Forms application demonstrates how to rotate a rectangle around an arbitrary point then perform mouse tracking and hit detection. This example uses Maui.Graphics and SkiaSharp with OpenGL.
Drawing Lines - This project demonstrates a simple way to draw lines in a Windows Form. Here we create a Bitmap then use a Graphics object to draw lines on it. The Bitmap is then assigned to PictureBox.Image and displayed to the user.
Drawing with the Mouse - This project uses a PictureBox's MouseMove event handler to create a MSPaint-like drawing surface with only a few lines of code.
Plotting on a 2D Coordinate System - A simple but challenging task when plotting data on a bitmap is the conversion between 2D data space and bitmap pixel coordinates. If your axis limits are -10 and +10 (horizontally and vertically), what pixel position on the bitmap corresponds to (-1.23, 3.21)? This example demonstrates a minimal-case unit-to-pixel method and uses it to plot X/Y data on a bitmap.
Modifying Bitmap Data in Memory - Bitmaps in memory have a certain number of bytes per pixel, so they're easy to convert to/from byte arrays. This example shows how to convert a Bitmap to a byte array, fill the array with random values, and convert it back to a Bitmap to display in a PictureBox. This method can be faster than using drawing methods like GetPixel and PutPixel.
Setting Pixel Intensity from a Value - This example shows how to create an 8-bit grayscale image where pixel intensities are calculated from a formula (but could easily be assigned from a data array). This example also demonstrates the important difference between Bitmap width and span when working with byte positions in memory.
Graphing Data with GnuPlot from C++ isn't Csharp-specific, but can be translated to any programming language. It demonstrates how easy it is to graph data from any programming language by saving it as a text file then launching gnuplot on it. Advanced data control and styling can be set with command line arguments (compiled-in), or defined in script files which give the end user the ability to modify styling without modifying the source code.
Realtime Microphone FFT Analysis is a new version of an older concept. This project uses a modern ScottPlot which has many improvements over older projects listed here.
DataView 1.0 is an interactive plotting control written using only the standard library. It allows panning/zooming by left-click-dragging the axis labels, moving the scrollbars, clicking the buttons, and also through right-click menus on the axis labels. Interactive draggable markers are also included. This control was designed to look similar to the commercial software ClampFit. I have decided to re-code this project from the ground-up, but the solution is frozen as-is (in a quite useful state) and the project page contains many notes of considerations and insights I had while developing it.
QRSS Spectrograph produces spectrographs which are very large (thousands of pixels) and very high frequency resolution (fractions of a Hz) intended to be used to decode slow-speed (1 letter per minute) frequency-shifting Morse code radio signals, a transmission mode known as QRSS. While functional as it is, this project is intended to be a jumping-off point for anybody interested in making a feature-rich QRSS viewer.
realtime audio spectrograph listens to your default recording device (microphone or StereoMix) and creates a 2d time vs. frequency plot where pixel values are relative to frequency power (in a linear or log scale). This project is demonstrated in a YouTube video. This example is not optimized for speed, but it is optimized for simplicity and should be very easy to learn from.
Microphone Level Monitor - This console application uses NAudio to continuously monitor the microphone and display audio levels by printing characters to the screen. Examples are provided for mono and stereo audio inputs.
realtime audio level meter uses NAudio to provide highspeed access to the microphone or recording device. This project is a minimal-case project intended to remind the author how to effeciently interact with incoming audio data.
realtime graph of microphone audio (RAW and FFT) Here I demonstrate a minimal-case example using the interactive graphing framework (below) to display audio values sampled from the microphone in real time. FFT () is also calculated and displayed interactively. See this project demonstrated on YouTube. Audio capture is achieved with nAudio and FFT with Accord. See FFT notes for additional details.
linear data speed rendering I greatly increased speed by drawing only single vertical lines (of small range min and max values) when the point density exceeds the horizontal pixel density. This is only suitable for evenly-spaced linear data (which is exactly what my target applications will be plotting). Performance is great, and there is plenty of room for improvement on the coding side too. AddLineXY() will be used to manually draw a line between every X,Y point in a list. AddLineSignal() graphs data from huge amounts of linear data by only graphing vertical lines.
intelligent axis labels This from-scratch re-code has separate classes for core plotting routines, data generation, and axis manipulation. Tick marks are quite intelligent as well. Included is a GUI demo (shown) as well as a 6 line console application which does the same thing (saving the output to a .jpg file instead of displaying it interactively).
interactive electrophysiology data Nearly identical to the previous example, except that there is a CSV button which loads an arbitrary string of values from data.csv if it is saved in the same folder as the exe. With minimal effort this program could be modified to directly load from ATF (Axon Text Format) files. With a little more effort, you could interface ABF files with the Axon pCLAMP ABF SDK.
interactive pan and zoom The ScottPlot class now has an advanced axis system. This makes it easily to set the viewing window in unit coordinates (X1, X2, Y1, Y2) and also do things like zoom and pan. This example was made to demonstrate these functions, as well as compare the speed of interactive graph manipulation at different sizes and with different quality settings. Although the GUI has many features, Form1.cs is not overwhelmingly complex.
stretchy line plot In this demo some random points are generated and scrolled (similar to numpy's roll method). Although the result looks simple, there is some strong thought behind how this example is coded. All the graphing code is encapsulated by the ScottPlot class of swhPlot.cs. The code of the GUI itself Form1.cs is virtually empty. My thinking is that from here I'll work on the graphing class, keeping gui usage as simple as possible. Note: plotting 321 data points I'm getting about 300Hz drawing rate with anti-aliasing off and 100Hz with it on
basic buffered line plot graphs data by creating a bitmap buffer, drawing on it with System.Drawing.Graphics (mostly DrawLines()) with customizable pens and quality (anti-aliasing), then displaying it onto a frame. The frame is resizable, which also resizes the bitmap buffer. Screen updates are timed and reported (at the bottom) so performance at different sizes can be assessed.
highspeed bitmap pixel access requires some consideration. This minimal-case project demonstrates how to set individual pixels of a bitmap buffer using the slower (simpler) setpixel method and the faster (but more complex) lockbits method. Once a bitmap buffer is modified, it is then applied to a pictutremap.

csharp-data-visualization's People

Contributors

dependabot[bot] avatar gosub-com avatar swharden avatar tgraupmann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csharp-data-visualization's Issues

A few questions regarding FFT Frequency

Thank you for your work on this project. I am working on a project myself on Raspberry Pi using Windows IoT (ie. UWP). Here are a few questions:

  1. I imagine if the nuget packages exist for .Net Core, then your project should still work. Any other thoughts on .Net Core?
  2. Your frequency range seems to start in the mid range frequency. For instance your voice is on the far left where it should perhaps be around the middle. Low bass will not register as it is. Thoughts on how to capture that?
  3. Is there any way to apply windowing to your frequency example? I am hoping that cleans up the frequency chart. I see you do use windowing in the spectrograph example.
  4. What are your thoughts on narrowing the number of frequencies. I am looking to get only 8 "bands". Think of a graphic eq with 8 frequncies. I suppose one option is manually adding everything between two frequencies. But hoping FFT would handle this.

Thank you for your input!

The Type or namespace "RectangleF' could not be found (are you missing a using directive or assembly reference)

  1. RectangleF: Error CS0246 The type or namespace name 'RectangleF' could not be found (are you missing a using directive or an assembly reference?)

  2. Quick Actions adds: "using System.Drawing" but this creates a conflict with Maui.Graphics and is the incorrect Rect type for
    the following line of code "canvas.FillRectangle(rect)" and other Maui.Graphics references (e.g., Color, convas, etc.).

  3. To test I added "using SDraw = System.Drawing" yielding SDraw.RectangleF rect = new( ... but as noted above RectangleF is wrong type for "canvas.FillRectangle(rect)".

  4. Added following and worked correctly:

Rect newRect = new(
                    x: columnIndex * cellWidthPx + xPad,
                    y: rowIndex * cellHeightPx + yPad,
                    width: cellWidthPx - xPad * 2,
                    height: cellHeightPx - yPad * 2);
canvas.FillRectangle(newRect);
  1. Fix is to use Maui.Graphics.Rect (rather than System.Drawing.RectangleF) .

In "realtime audio spectrograph" exist int fft_size. It's define height of the image. But how it's define the input array into blocks?

You copy from unanalyzed_values array with fft_size elements, and process. After it you delete from unanalyzed_values fft_size / pixelsPerBuffer values. Seems fft_size / pixelsPerBuffer != fft_size. Also, if unanalyzed_values has too much values - you delete some of it.
How you understand, where new audio sample starts, and ends? Why sample of music, that code process should be the same, as fft_size and start at the same position?

Does this work with ASIO?

Hi there,

I am making a hardware device that has a rgb ledstrip connected to it.
I wanted to react the ledstrip on the music. But I also wan't it to work with ASIO.
Because there are a lot of music producers that are in need of a reactive sound rgb ledstrip that work with fl studio or another daw. Most of them are using ASIO.

Is this possible?

update ScottPlot in old projects

All code examples in this repository used a pre-release version of ScottPlot. Because the ScottPlot API changed so much since then, these old projects cannot use the latest ScottPlot. Each project contains a subfolder with a version-matched scottplot (sometimes zipped, renamed, or not included to avoid people from using it before it was released).

  • Add notes about the new ScottPlot. Many old projects in this repo use an old version of ScottPlot. Add notes and links to the new ScottPlot project page (which didn't exist when the project was first made).

  • Create an new demo that shows how to plot microhone PCM (amplitude) and FFT (frequency) data in real time using the new ScottPlot API.

How to, Detect sound Frequancy sample ( 10KHZ )

hi,
example 17-07-16_microphone running ok

how to, Detect sample especifique frequency, example: 1000k, 5000k, or....11000, 18000khz

processing data sample (10ms), serarch in sample save buffer.

thanks,
Carlos.

Problem with conversion to Int16

Hi, I was trying out your project, and found the input on my laptop to be erratic.

Clipping and overshooting of the samples.

Checking your conversion from bytes to Int16 and then to double raised some suspicion.
The data coming from my card seems to be signed, and due to some auto leveling feature, your conversion seems to work fine when i turn down the mics volume.

When changing the conversion to use BitConversion:
Int16 val = BitConverter.ToInt16(audioBytes, i * 2);

The application started behaving as expected.

WPF: What is the best way to achieve continuous rendering?

Remove the Timer from the "MainWindow" and replace it with.

private void Checkbox1_Checked(object     sender, RoutedEventArgs e) => CompositionTarget.Rendering += CompositionTarget_Rendering;
private void Checkbox1_Unchecked(object   sender, RoutedEventArgs e) => CompositionTarget.Rendering -= CompositionTarget_Rendering;
private void CompositionTarget_Rendering(object? sender, EventArgs e)
{
    SkElement1.InvalidateVisual();
}

Values go out of graph area

Hello, I am working with 18-01-15_form_drawing project and trying to change y axis values with strings. I did and it looks normal until using zoom. when I zoom to axis my values go out the graph. When I scroll the bar, values look in graph area. Could you please help mi? Thank you.
vertical_axis_code
in_area
out_of_zoom

FFt audiomonitor output hangs after a few minutes, or skips

Hello, i built a huge music visualizer on top of your FFT Graph, only to find it breaks pretty consistenly.

Solution was simple, but took me 5 days.

Divide the sample rate down to 10 milliseconds, just like the waveform monitor.

Its the only way

ImageSharp's relationship with the .NET Foundation

In October 2022 ImageSharp announced they are leaving the .NET foundation:

This is the result of SixLabors changing the terms of their license in July 2022 and being unable to resolve the conflict with the .NET Foundation

The .NET Foundation made a blog post discussing the change (which they later deleted):

The .NET Foundation only works with projects with OSI-approved licenses. ImageSharp has decided to leave the Foundation ... We don’t see a path forward where we maintain a fork of ImageSharp.

After significant consideration, the .NET Foundation board decided that there wasn’t a path forward that satisfied the goals of both Six Labors and the Foundation. The board clarified that projects in the Foundation must use a permissive OSI-approved license and that projects would all be treated the same.

Also, the 2.x NuGet packages will not be deleted. You’ll be able to use those forever.

The official System.Drawing documentation page no longer recommends ImageSharp as an alternative to System.Drawing. Interesting discussion about the removal of this recommendation can be found on the PR that removed the link:

Discussions related to ImageSharp leaving the .NET Foundation:

Considering the .NET Foundation's page describing these events is now 404'd and ImageSharp is still on the .NET Foundation projects page it seems this story is still unfolding:

After the dust settles, a summary of these events and relevant links should be added to the page:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.