GithubHelp home page GithubHelp logo

spm / spm Goto Github PK

View Code? Open in Web Editor NEW
60.0 10.0 19.0 745.64 MB

SPM (Statistical Parametric Mapping) - Development Version

Home Page: https://www.fil.ion.ucl.ac.uk/spm/

License: GNU General Public License v2.0

MATLAB 89.28% Makefile 0.10% C 9.34% Shell 0.04% Roff 0.02% HTML 0.03% CSS 0.01% Smarty 0.01% C++ 0.63% M 0.01% Cuda 0.32% Mathematica 0.23%
matlab neuroscience neuroimaging spm eeg fmri meg pet spect mapping

spm's Introduction

   ___  ____  __  __
  / __)(  _ \(  \/  )  
  \__ \ )___/ )    (   Statistical Parametric Mapping
  (___/(__)  (_/\/\_)  SPM - https://www.fil.ion.ucl.ac.uk/spm/

Platform: MATLAB Open in MATLAB Online License: GPL Tests

This README gives a brief introduction to the SPM software. Full details can be found on the SPM website.

See also Contents.m, AUTHORS.txt and LICENCE.

SPM

Statistical Parametric Mapping refers to the construction and assessment of spatially extended statistical process used to test hypotheses about functional imaging data. These ideas have been instantiated in software that is called SPM. The SPM software package has been designed for the analysis of brain imaging data sequences. The sequences can be a series of images from different cohorts, or time-series from the same subject. The current release is designed for the analysis of fMRI, PET, SPECT, EEG and MEG.

Please refer to this version as "SPM12" in papers and communications.

SPM was written to organise and interpret our data (at The Wellcome Centre for Human Neuroimaging). The distributed version is the same as that we use ourselves.

SPM is made freely available to the [neuro]imaging community, to promote collaboration and a common analysis scheme across laboratories.

Software

The SPM software is a suite of MATLAB functions, scripts and data files, with some externally compiled C routines, implementing Statistical Parametric Mapping. MATLAB, a commercial engineering mathematics package, is required to use SPM. MATLAB is produced by MathWorks, Natick, MA, USA.

SPM requires only core MATLAB to run (no special toolboxes are required).

SPM12 is written for MATLAB version 7.4 (R2007a) onwards under Windows, Linux and Mac (SPM12 will not work with versions of MATLAB prior to 7.4). Binaries of the external C-MEX routines are provided for Windows, Linux and Mac. The source code is supplied and can be compiled with a C compiler (Makefile provided).

See https://www.fil.ion.ucl.ac.uk/spm/software/spm12/ for details.

Later versions of MATLAB (released after SPM12), will probably need additional patches in order to run. Once developed, these will be made available from: https://www.fil.ion.ucl.ac.uk/spm/download/spm12_updates/

Although SPM12 will read image files from previous versions of SPM, there are differences in the algorithms, templates and models used. Therefore, we recommend you use a single SPM version for any given project.

The SPM12 Release Notes can be found online: https://www.fil.ion.ucl.ac.uk/spm/software/spm12/

File format

SPM12 uses the NIFTI-1 data format as standard. Take a look at https://nifti.nimh.nih.gov/ for more information on the NIFTI-1 file format.

The old SPM2 version of Analyze format can be read straight into SPM12, but results will be written out as NIFTI-1. If you still use this format, then it is important that you ensure that spm_flip_analyze_images has been set appropriately for your data.

The MINC and ECAT7 formats can not be read straight into SPM12, although conversion utilities have been provided. Similarly, a number of DICOM flavours can also be converted to NIFTI-1 using tools in SPM12.

Resources

The SPM website is the central repository for SPM resources: https://www.fil.ion.ucl.ac.uk/spm/

Introductory material, installation details, documentation, course details and patches are published on the site.

There is an SPM email discussion list, hosted at [email protected]. The list is monitored by the authors, and discusses theoretical, methodological and practical issues of Statistical Parametric Mapping and SPM. The SPM website has further details: https://www.fil.ion.ucl.ac.uk/spm/support/

Please report bugs to the authors at [email protected].

Peculiarities may actually be features, and should be raised on the SPM email discussion list, [email protected].

Authors

SPM is developed under the auspices of Functional Imaging Laboratory (FIL), The Wellcome Centre for Human NeuroImaging, in the Queen Square Institute of Neurology at University College London (UCL), UK.

SPM94 was written primarily by Karl Friston in the first half of 1994, with assistance from John Ashburner (MRC-CU), Jon Heather (WDoIN), and Andrew Holmes (Department of Statistics, University of Glasgow). Subsequent development, under the direction of Prof. Karl Friston at the Wellcome Department of Imaging Neuroscience, has benefited from substantial input (technical and theoretical) from: John Ashburner (WDoIN), Andrew Holmes (WDoIN & Robertson Centre for Biostatistics, University of Glasgow, Scotland), Jean-Baptiste Poline (WDoIN & CEA/DRM/SHFJ, Orsay, France), Christian Buechel (WDoIN), Matthew Brett (MRC-CBU, Cambridge, England), Chloe Hutton (WDoIN) and Keith Worsley (Department of Statistics, McGill University, Montreal Canada).

See AUTHORS.txt for a complete list of SPM co-authors.

We would like to thank everyone who has provided feedback on SPM.

Disclaimer, copyright & licencing

SPM is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

SPM is supplied as is: No formal support or maintenance is provided or implied.

Copyright (C) 1991,1994-2023 Wellcome Centre for Human Neuroimaging

spm's People

Contributors

adeelrazi avatar balbasty avatar barnesgr123 avatar bernadettevanwijk avatar brudfors avatar christophephillips avatar friston avatar georgeoneill avatar gllmflndn avatar jbpoline avatar jdaunize avatar jmattout avatar jmkilner avatar johmedr avatar johnashburner avatar mjduarterosa avatar nicholst avatar nicolelabravila avatar pzeidman avatar ridgwaygr avatar rikhenson avatar rosalynmoran avatar spmcentral avatar spmdeveloper2021 avatar stefankiebel avatar tejparr avatar tierneytim avatar vlitvak avatar volkmarglauche avatar wpennyuea 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spm's Issues

AAL3 toolbox issue

Hello there, I'm new to the community. I operate from a 2015 Macbook Air using Matlab 2019a, but also had the same issue on Linux machine. I need to use the Automated Anatomical Labeling (AAL) toolbox in order to process some PET data. I downloaded the latest version (AAL3v1) from https://www.gin.cnrs.fr/en/tools/aal/ and then followed the instructions in 'AAL User guide' (https://www.gin.cnrs.fr/wp-content/uploads/AAL3_UserGuide_June2020.pdf) to install the software, which are: move zip to toolbox folder of spm, unzip, copy masks to the newly created atlas folder in spm. The toolbox is then available on the spm GUI's toolbox list but doesn't allow to select any of the data and matlab gives this error:

AAL3
Dot indexing is not supported for variables of this type.

Error in gin_list_dlabels (line 84)
S = varargin{2}.S;

Error in gin_dlabels (line 28)
gin_list_dlabels('List',xSPM,hReg);

Error while evaluating UIControl Callback.

This happens as well trying to open AAL3 directly from Matlab's command window or 'Results' section in sum GUI.
Can anyone help? Thank you lots

Powell's optimization methods without using derivatives

Hi, SPM maintainers,

I noted that you are using Powell's conjugate direction method as an optimization solver: https://github.com/spm/spm/blob/main/spm_powell.m

While this is an excellent method of Powell's, he developed a few other solvers that do not use derivatives. I am responsible for the maintenance of these solvers after Professor Powell passed. They may work (much) better on your problems. You may have a look if interested: https://github.com/libprima/prima .

Hope they will be helpful to you.

Best regards,
Zaikun Zhang
PhD and Assistant Professor
Hong Kong Polytechnic University

Adding BIDS-Prov support in SPM

As discussed with @gllmflndn on July 24th, here is the rationale to implement BIDS-Prov in SPM.

The BIDS-Prov export will be obtained by adding a new call to spm_jobman with the first parameter set to 'prov':

[output_list, harvested_job] = spm_jobman('run', my_job);
spm_jobman('prov', output_list, harvested_job);

To export SPM batch files as BIDS-Prov:

  • output_list will be used to create the output entities, one entity per filename found (tested as a heuristic to determine whether it is a filename) and each entity is linked back to the activity with wasGeneratedBy
  • harvested_job contains the path to all files (including the dependencies that have been replaced by the actual file path on disk) and is used in combination with config file spm_cfg_** to determine which files are inputs (those are defined as cfg_files in the corresponding spm_cfg_**)
  • Labels for activities will be retrieved in the first line of the help of the corresponding module.

Useful resources :

spm_copy, copy jsons when unzipping nifti files

Dear all,

the spm wikibook, has an example for using spm_copy showcasing, that it can do unzipping and copies the accompanying meta-data with it.

spm_copy('sub-2475376_task-rest_bold.nii.gz','/derivatives', 'nifti',true, 'gunzip',true)

That is in fact not what is happening, as in spm_copy lines 69-72

        elseif strcmp(spm_file(source{i},'ext'),'nii') 
            sts = copyfile(spm_file(source{i},'ext','mat'), dest{i}, opts.mode{:});
            sts = copyfile(spm_file(source{i},'ext','json'), dest{i}, opts.mode{:});
        end

.json and .mat files are only copied, when the source image is a .nii (or .img) file.

I think adjusting the spm_copy function to match the documentation would be helpful.

Happy to makae a pull-request, but would appreciate some pointers as it would be necessary two remove both .nii and .gz from the file name to copy the metadata.

Best wishes!

Creating Template with DARTEL fails

I segmented a bunch of MR images in spm. When trying to create a template in DARTEL, I cannot select multiple files for some reason. I am getting this error messages:

invalid dot name structure assignment because the structure array is empty. Specify a subscript on the
structure array to resolve.

/path/to/spm12-r7771/toolbox/DARTEL/spm_dartel_template.m" (v7182), function "spm_dartel_template" at
line 49..

I can create templates if I specify only a single file on single and/or multiple image channels. I highly doubt this is an OS specific issue but I'll leave my runtime env here:

OS: Arch Linux x86_64
Kernel: 5.16.0-arch1-1

Plus I am using spm on GNU Octave and compiled it from the instructions I found here.

'cfg_files' error

When initialising SPM, MATLAB throws this:

Initialising batch system... Failed to load E:\Workspace\Toolbox\matlabbatch\cfg_mlbatch_appcfg.m
Error using cfg_files
The class 'cfg_files' is used in its own class definition as a base class, property value, or attribute value. This is not allowed.
In file "E:\Workspace\Toolbox\spm12\matlabbatch\cfg_util.m" (v7345), function "local_initapps" at line 1478.
In file "E:\Workspace\Toolbox\spm12\matlabbatch\cfg_util.m" (v7345), function "cfg_util" at line 743.
In file "E:\Workspace\Toolbox\spm12\spm_jobman.m" (v7744), function "spm_jobman" at line 189.
In file "E:\Workspace\Toolbox\spm12\spm_jobman.m" (v7744), function "spm_jobman" at line 108.

First initialisation is usually successfull, but when I have to restart SPM, it throws an error after an error, all about cfg_something, and I have to restart MATLAB.
Not a major deal, I only have to restart while experimenting with various stuff for my scripts, and running the debugged ones does not have this issue, but it's very annoying.

Win10 x64
MATLAB 2021a
SPM 7771 (latest release)

I think this might be related: https://www.mathworks.com/help/simulink/ug/how-working-with-matlab-classes-is-different-for-code-generation.html

Normalise

Because of the requirements of the university, I need to know how Normalise: Write works. Can I find the code or function of Normalize: Write here? Also, I want to ask whether the Deformation Field is linear or non-linear? Thank you for your answers.

Bug in DICOM import: MRScaleSlope/MRScaleIntercept with more than 1 value

A user reported this bug on the Brainstorm forum:
https://neuroimage.usc.edu/forums/t/import-mri-error/37412

After testing with the DICOM folder the user provided, I found that MRScaleSlope/MRScaleIntercept have more than one value.
Debugger at line 625 of spm_dicom_convert shows:

K>> Headers{1}.MRScaleSlope
ans =
   147   109    39    59

K>> Headers{1}.MRScaleIntercept
ans =
     0     0     0     0

This is not handled in the function, it causes the following error:

** Error: Line 625:   / 
** Matrix dimensions must agree.
** 
** Call stack:
** >spm_dicom_convert.m>WriteVolume at 625
** >spm_dicom_convert.m>ConvertStandard at 246
** >spm_dicom_convert.m at 72

@gllmflndn I'll send you the DICOM folder by email (this is not public data).

Related to this commit:
5ea021b

spm('ver') handling in the future

As predicted in this commit removing the version number from the Contents.m means the command spm('ver') returns just SPM, which in turn will break 3rd party support.

Ironically this means in the development version it breaks FieldTrip, which in turn breaks some SPM functionality.

I've noticed that this breaks how FieldTrip determines which version of SPM is on the path as Contents.m no longer (for the dev version at least) returns a version number. There's elements of DAiSS which rely on FT being able to determine which version of SPM is present to run - for example, using FT to interpoalate NIFTI images for exporting.

So two things we need to resolve.

  1. Shall we raise an issue in FT to handle the dev (i.e versionless) version.
  2. What's the plan for versioning going forward, so we dont have to implement another patch when we start considering calendar releases?

Trouble with NaN duration of fMRI event.

We encountered a weird issue with some basic fMRI designs and tracked the problem to some events being defined with a NaN value instead of a numeral value. This should NOT happen of course but it still occurred because of the way the events.mat file (with the names, onsets and durations variables) was automatically created from the experiment log-files recorded at the scanner1. Then with 10's of subjects to process, everything was pipelined till the group-level analysis.

Description

Now the problem is easy to reproduce with a "design only" fMRI model specification, so here is a simple example:

  • regular model with 4 block events for 1 condition with onsets at [15 50 85 120]s and durations [20 20 20 20]s
    GLM_orig
  • same model but the duration of the 3rd event is set to NaN, i.e. [20 20 NaN 20]s
    GLM_NaN

Tracking how the duration values are employed, the weird behavior stems from line 131 in spm_get_ons.m

tof       = max(tof,1);

where tof encodes the events offset (in microtime bins) and tof = [ 314 594 NaN 1154]'. The max(tof,1) operation turns it into tof = [ 314 594 1 1154]', which leads to a stimulus function sf

sf =
   (1,1)       -1
 (153,1)        1
 (314,1)       -1
 (433,1)        1
 (594,1)       -1
 (713,1)        1
 (993,1)        1
(1154,1)       -1

then the stimulus time course looks like
StimFunc_NaN
because of the -1 placed in the 1st time bin 2.

Solution?

Could there be some check on the duration value at some point during the creation of the GLM?
This would have saved us, and maybe others?, some stress...

Footnotes

  1. when the subject in the scanner did not press any response button after the stimulus, there was no "button press" time and it ended up being read a NaN.

  2. the correct tof would look like [ 314 594 874 1154]' and there is a clean 1/-1 pattern in the sf variable.

spm_jsonread: parsing incorrect json file

Hi,

In the current implementation, spm_jsonread do not report syntax errors in the json file that he attempt to read. For example, if input json is (no comma between second and third lines):

{
  "aa": "1",
  "bb": "2"
  "cc": "3"
}

spm_jsonread parses as:

  struct with fields:

    aa: '1'
    bb: '2'

The line cc is ignored without any error/or warning, which can lead to the difficult to track errors downstream.

Can spm report the error?

Unrecognized 'cfg_branch' when using 'spm_image.m'

When attempting to display a correct T1.nii file using the spm_image function in MATLAB's SPM toolbox (spm_image('Display', fileT1);), the following error is encountered:

Error in cfg_getfile>reg_filter (Line 1185)
dprms = {cfg_branch};

Error in cfg_getfile (Line 177 )
t = reg_filter(varargin{2:end});

Error in spm_select (Line 115)
cfg_getfile('regfilter', 'mesh', {'.gii$'});

Error in spm_select (Line 110)
spm_select('regfilter');

Error in spm_select (Line 97)
spm_select('init');

Error in spm (第 919 行)
fn = cellstr(spm_select('List',tdir,['^.*' d{j} '.m$']));

Error in spm_orthviews>reset_st (Line 1551)
xTB = spm('TBs');

Error in spm_orthviews (Line 251)
if isempty(st), reset_st; end

Error in spm_image (Line376)
spm_orthviews('Reset');

Error in spm_image>init_display (Line 398)
spm_image('Reset');

Error in spm_image (Line 87)
init_display(P);

Error in corregister_normalize_Images (Line 29)
spm_image('Display',fileT1);

Reinstallation of SPM toolbox did not resolve the issue.
And I re-install SPM, it can't work. Seeking guidance on resolving this error and successfully displaying T1.nii files using the spm_image function in SPM toolbox. Thx!

Windows 11 Performance

I am experiencing some severe performance issues on Windows 11 that are not present on Ubuntu 22.04. For instance, smoothing a functional file containing 375 volumes takes around 9 seconds on Ubuntu and around 3 minutes on Windows 11. This is using the SPM version from the main branch with MATLAB R2022a on both systems. I have also tested with MATLAB 2021a on Windows 11 and the issue persists.

Similarly, realigning this image take around 5 minutes on Windows 11. Most of this time is spent hanging in between estimating the realignment and the reslicing. When I interrupt the process, it seems to be stuck within the write_hdr_raw function called from create, which is writing out the new headers after estimation. This alone for the 375 volumes is taking around 4 minutes on Windows 11, which clearly is not right. I do not know if something is being called recursively or why this would affect Windows 11 and not Ubuntu 22.04.

The data I am using for testing is the following functional file from OpenNeuro: https://openneuro.org/crn/datasets/ds000157/snapshots/00001/files/sub-01:func:sub-01_task-passiveimageviewing_bold.nii.gz Simply gunzipping the file (with the batch) and running a basic realign: estimate & reslice is enough for me to experience the 4 minute hang between estimation and reslicing.

Add Support for MacOS Apple M1 Chip

Currently, due to this line, SPM does not work on a machine using the Apple M1 Chip.

Thus, when someone with a new Macbook tries to use SPM, the following error occurs:

Error using spm_platform>init_platform
MACA64 not supported architecture for SPM12

'sensor' struct not being updated when cropping MEEG object

Hello @tierneytim @vlitvak

I am raising the issue as a formality after an in person chat with @tierneytim. Thank you in advance for your time.

It seems that the function spm_eeg_crop() is not updating the 'sensors' structure in the new MEEG object following the cropping, even though other fields such as 'chanlabels' are updated for the Dnew (see screenshot below).*

I have used the spm_eeg_crop() to crop out 2 channels which switched off halfway through the OPM recording session (such that half of the blocks had the channels, whereas the other did not. It was necessary to remove that difference as otherwise it was not possible to merge the blocks from the same session due to size incompatibility of the MEEG objects of different blocks).

Whilst channels and sensors are not linked in SPM and it would not usually be the problem, the lack of updating 'sensors' struct became a problem to me when trying to use spm_opm_hfc() (specific error: error('data size ~= number of sensors with orientation information'));

This is because spm_opm_hfc() draws information from the 'sensors' struct (and there are subfields for sensors corresponding to the channels which no longer exist).

I have overcame this problem by updating the 'sensor' struct separately, using code below**. An alternative was to first run the hfc and crop the channels just before merging. However, some 3D source localisation methods may require sensor information which could lead to recurrence of the problem if the 'sensors' is not updated. Let me know if the 'sensor' struct should not be updated as below, or otherwise a similar approach could be incorporated inside the spm_eeg_crop().


  • from inside the spm_eeg_crop() where channel information is updated but I do not think sensors are
    image

*updating the 'sensors' struct to no longer include the channels cropped out with spm_eeg_crop(), run after the cropping itself (please let me know in case there are errors).

for block_counter = 1:length(block)
   cropped_channel_labels{block_counter} = D{block_counter}.chanlabels(indchantype(D{block_counter}, 'MEG'))';
   non_cropped_sensor_labels{block_counter} = sensors(D{block_counter}, 'MEG').label;
   % define indices of sensors consistent with the cropped list of
   % channels (i.e., do not include indices of the cropped sensors)
   ind{block_counter} = find(contains(non_cropped_sensor_labels{block_counter},cropped_channel_labels{block_counter}));
   grad = D{block_counter}.sensors('MEG');
   gradnew = grad;
   gradnew.chanori = grad.chanori(ind{block_counter},:);
   gradnew.chanpos = grad.chanpos(ind{block_counter},:);
   gradnew.chantype = grad.chantype(ind{block_counter},:);
   gradnew.chanunit = grad.chanunit(ind{block_counter},:);
   gradnew.coilori = grad.coilori(ind{block_counter},:);
   gradnew.label = grad.label(ind{block_counter},:);
   gradnew.coilpos = grad.coilpos(ind{block_counter},:);
   % change size in both dimensions for .tra
   gradnew.tra = grad.tra(ind{block_counter},ind{block_counter});
   D{block_counter} = sensors(D{block_counter}, 'MEG', gradnew);
   save(D{block_counter});
end

Question about first level analysis

Hello, I'm Keren, a doctoral student conducting my first MRI scans and using SPM. I've encountered an issue and would appreciate some help. My motor task involves two conditions: in the first condition, the subject needs to reach a stimulus at a fixed location, and in the second condition, the subject needs to reach with their finger to a stimulus at an unknown location. When comparing each condition to rest, I observe activity in expected areas like the motor and visual cortex. However, when I contrast the condition with the unknown location against the known one, I'm seeing activity in various brain regions, including the Ventricles. Does anyone have ideas why I am getting this result (which is consistent across most subjects)

. Does anyone know how I can add a condition in the SPM GUI that shows the contrast of activity in the first condition less activity in the second condition but only the positive betas? (I thought that perhaps the betas in both conditions are negative, leading to the display of brain activity in the ventricles)

Spelling corrections

There is an opportunity to make spelling corrections to the subset of non-external files mentioned in this now-closed pull request by @yariktopic - #18

4D NIfTI files are processed slower compared to 3D NIfTI files

Hello,

When I work with 4D NIfTI files and do smoothing on the images, the process takes much longer so I have to use 3D NIfTI instead. I think this issue is a problem with Windows platform and does not seem to be related to antivirus.

I am happy to try helping solve this issue if it is not replicable on the computers which the developers have access to.

SPM Standalone Error - "Warning: dialog is no longer supported when MATLAB is started with the -nodisplay"

Hello SPM experts,

I am having difficulties running a Matlab script with the SPM standalone in a Ubuntu Docker container. Although I have set "SPM_HTML_BROWSER=0" (as suggested by the docs), I still have an error related to the UI not being supported by Matlab in a docker container.

Error which stops fMRI model specification:
Screenshot 2024-03-11 at 1 44 14 PM

After this warning occurs, the script hangs.

I am calling SPM standalone as the following:

./run_spm12.sh $MCR_PATH script myscript.m <script args>

Does anyone have help for this? It seems like there should be an environment variable or config to prevent this UI component from being shown.

Environment information:

SPM Standalone:
https://www.fil.ion.ucl.ac.uk/spm/download/restricted/utopia/spm12/spm12_r7771_Linux_R2022b.zip

MCR: Matlab 2022b

Ubuntu:latest

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.