Coder Social home page Coder Social logo

juliagraphics / colors.jl Goto Github PK

View Code? Open in Web Editor NEW
199.0 8.0 71.0 4.34 MB

Color manipulation utilities for Julia

License: Other

Julia 100.00%
color colors colour colours color-manipulation color-conversion color-scheme color-schemes colorschemes gradients

colors.jl's People

Contributors

carstenbauer avatar cormullion avatar dcjones avatar femtocleaner[bot] avatar fredrikekre avatar garrison avatar github-actions[bot] avatar glennsweeney avatar ianbutterworth avatar jakebolewski avatar jeffbezanson avatar jiahao avatar johnnychen94 avatar juliohm avatar jwmerrill avatar kimikage avatar kmsquire avatar natj avatar rdeits avatar rickhg12hs avatar simondanisch avatar staticfloat avatar stefankarpinski avatar stevengj avatar t-bltg avatar tbreloff avatar timholy avatar vtjnash avatar waldyrious avatar yuyichao 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

colors.jl's Issues

Conversion from Lab -> RGB -> Lab is wrong for some inputs

For example:

julia> Lab(RGB(Lab{Float32}(8, -100, 74)))
Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)

This is the root cause of JuliaIO/QuartzImageIO.jl#43

Using TraceCalls.jl shows the following:

x = Lab{Float32}(8, -100, 74)
@show x
display(@trace Colors Lab(RGB(x)))
x = Lab{Float32}(8.0f0,-100.0f0,74.0f0)
- #1() => Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)
   - ColorTypes._convert(ColorTypes.RGB{Float32}, ColorTypes.RGB, ColorTypes.Lab, Lab{Float32}(8.0f0,-100.0f0,74.0f0)) => RGB{Float32}(0.0f0,0.19099429f0,0.0f0)
      - Colors.cnvt(ColorTypes.RGB{Float32}, Lab{Float32}(8.0f0,-100.0f0,74.0f0)) => RGB{Float32}(0.0f0,0.19099429f0,0.0f0)
         - ColorTypes._convert(ColorTypes.XYZ{Float32}, ColorTypes.XYZ, ColorTypes.Lab, Lab{Float32}(8.0f0,-100.0f0,74.0f0)) => XYZ{Float32}(-0.015993804f0,0.008856452f0,-0.042092435f0)
            - Colors.cnvt(ColorTypes.XYZ{Float32}, Lab{Float32}(8.0f0,-100.0f0,74.0f0)) => XYZ{Float32}(-0.015993804f0,0.008856452f0,-0.042092435f0)
               - convert(ColorTypes.XYZ{Float32}, Lab{Float32}(8.0f0,-100.0f0,74.0f0), XYZ{Float64}(0.95047,1.0,1.08883)) => XYZ{Float32}(-0.015993804f0,0.008856452f0,-0.042092435f0)
                  - Colors.cnvt(ColorTypes.XYZ{Float32}, Lab{Float32}(8.0f0,-100.0f0,74.0f0), XYZ{Float64}(0.95047,1.0,1.08883)) => XYZ{Float32}(-0.015993804f0,0.008856452f0,-0.042092435f0)
         - Colors.cnvt(ColorTypes.RGB{Float32}, XYZ{Float32}(-0.015993804f0,0.008856452f0,-0.042092435f0)) => RGB{Float32}(0.0f0,0.19099429f0,0.0f0)
            - Colors.srgb_compand(-0.044456381371432444) => -0.5743764473189071
            - Colors.clamp01(-0.5743764473189071) => 0.0
            - Colors.srgb_compand(0.030367856677316497) => 0.19099428547111136
            - Colors.clamp01(0.19099428547111136) => 0.19099428547111136
            - Colors.srgb_compand(-0.04719807830026346) => -0.6097991716394039
            - Colors.clamp01(-0.6097991716394039) => 0.0
   - ColorTypes._convert(ColorTypes.Lab{Float32}, ColorTypes.Lab, ColorTypes.RGB, RGB{Float32}(0.0f0,0.19099429f0,0.0f0)) => Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)
      - Colors.cnvt(ColorTypes.Lab{Float32}, RGB{Float32}(0.0f0,0.19099429f0,0.0f0)) => Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)
         - ColorTypes._convert(ColorTypes.XYZ{Float32}, ColorTypes.XYZ, ColorTypes.RGB, RGB{Float32}(0.0f0,0.19099429f0,0.0f0)) => XYZ{Float32}(0.010858821f0,0.021717642f0,0.003619606f0)
            - Colors.cnvt(ColorTypes.XYZ{Float32}, RGB{Float32}(0.0f0,0.19099429f0,0.0f0)) => XYZ{Float32}(0.010858821f0,0.021717642f0,0.003619606f0)
               - Colors.invert_rgb_compand(0.0f0) => 0.0
               - Colors.invert_rgb_compand(0.19099429f0) => 0.030367858759125482
               - Colors.invert_rgb_compand(0.0f0) => 0.0
         - ColorTypes._convert(ColorTypes.Lab{Float32}, ColorTypes.Lab, ColorTypes.XYZ, XYZ{Float32}(0.010858821f0,0.021717642f0,0.003619606f0)) => Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)
            - Colors.cnvt(ColorTypes.Lab{Float32}, XYZ{Float32}(0.010858821f0,0.021717642f0,0.003619606f0)) => Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)
               - Colors.cnvt(ColorTypes.Lab{Float32}, XYZ{Float32}(0.010858821f0,0.021717642f0,0.003619606f0), XYZ{Float64}(0.95047,1.0,1.08883)) => Lab{Float32}(16.364f0,-26.887983f0,23.036493f0)
                  - Colors.fxyz2lab(0.011424685420170435) => 0.2252240429769683
                  - Colors.fxyz2lab(0.02171764150261879) => 0.2790000107167975
                  - Colors.fxyz2lab(0.0033243076588359457) => 0.16381754134462

Gamma correction

In view of @timholy's recent pull request, I thought I'd better raise the topic of Gamma, since we are concerned with being as correct as possible.
In brief, gamma correction is a nonlinear mapping applied to digital images at both capture and display, with the result that images are displayed in linear light. (In TV, this is largely an artefact of backwards compatible standards since the time of PAL/NTSC and not forcing everyone to buy new tellies.) The upshot for this package is that some* images do not record linear light (in a particular channel) rather, the sensor records linear light, then a process in the camera maps it to a non-linear space.
The bad news is that few (TV) camera manufacturers follow the standards precisely, opting instead for a particular "look" which is close to the standard, but not exact. Again, I can't say with certainty what happens with digital stills cameras. But unless the operating system is doing some very complicated pixel-wise gamma in the display, almost all digital image formats come with gamma-encoded pixels.

Having a brief look through the code, some support for this is already in place. Converting XYZ to RGB applies gamma (the function srgb_compand), but I can't see any of the conversions from RGB to other spaces undoing the gamma first.

Some possible solutions:

  • Do nothing. This is how gamma is dealt with in most computer vision applications.
  • Square RGB values to approximately convert to linear light before processing. This suggestion courtesy of Tim Borer, one of the authors of the paper mentioned here[1].
  • Apply the sRGB/Rec709 gamma correction to RGB images, with an external interface to allow the user to specify their own function or look-up table for other colour spaces.

I imagine that the best solution will be very application specific. The errors introduced by doing nothing are usually very small, which is why most applications ignore them. But in feature film production, and some graphics applications they are treated more carefully. Currently, I handle gamma by creating custom image reading functions which first call imread, then apply whatever correction I choose before returning the image.

*I'm afraid I have no idea how widespread this is. TV cameras encodes gamma-corrected pixels. Digital film cameras do various manufacturer-specific things in an attempt to mimic the dynamic response of film to illumination, and the development process, which also involve non-linear encodings. The wikipedia[2] seems to suggest that digital stills cameras also encode gamma-corrected pixels. A remark @stevengj made about how MIME types work suggests that modern operating systems do not necessarily apply the same gamma correction to all images, but my anecdotal experience of looking at lots of images that I've de-gammaed doesn't support this. I'd be interested to learn more.

[1]http://www.ibc.org/page.cfm/action=library/libID=14/libEntryID=106/listID=2
[2] https://en.wikipedia.org/wiki/Gamma_correction

(edits for markdown formatting)

Starting a ColorMaps package

Hello colleagues,

i'd like to take the initiative and start a color maps package with the scope:

  • provide standard colormaps (i.e. jet, matplotlib options A ...D, other 'know' industry standards)
  • code to construct colormaps (from parameters or constraints)

@tbreloff already offered the possibility to inherit code that is actually in Plots.jl right now.
And from my perspective other code from e.g. Colors.jl could be moved there also.

Could someone from the Group please raise my permissions, so i can directly start the repository under JuliaGraphics?

Supporting addition/averaging in color spaces other than RGB

According to this question
http://stackoverflow.com/questions/649454/what-is-the-best-way-to-average-two-colors-that-define-a-linear-gradient
it seems LAB is the most appropriate space to do color averaging in. Yet it seems averaging isn't supported in that space. I'm wondering whether we can add support for that.

Or, this could possibly be very silly, is there a way I can access the color coordinate of type LAB so I can do operations on these numeric values directly.

I submitted this issue under the Color package as well but it seems this package is maintained more frequently. Please close the duplicates if necessary.

convert of `Gray{Bool}` to `RGB` fails

Just as I was trying to extend the tests for the hex function the following failed:

julia> convert(RGB,Gray{Bool}(1))
ERROR: TypeError: RGB: in T, expected T<:Union{AbstractFloat,FixedPointNumbers.FixedPoint{T<:Integer,f}}, got Type{Bool}
 in convert(::Type{ColorTypes.RGB}, ::ColorTypes.Gray{Bool}) at ~/.julia/v0.5/ColorTypes/src/conversions.jl:7

Is this Bug known?

A way to make distinguishable_colors output darker, for use on white backgrounds?

I like using distinguishable_colors with PyPlot, but find that with thin line thicknesses, some of the the colors wash out on a white background (see yellow below). Is there a simple way to weight the process towards darker colors?

using PyPlot, Colors
vars = 1:10
cols = distinguishable_colors(length(vars))
plot_cols = map(col->(red(col),green(col),blue(col)),cols)
for i = 1:length(vars)
    plot(1:10,rand(10),"-o",c = plot_cols[i],linewidth=0.5,markersize=1)
end

image

distinguishable_colors for ColorAlpha?

I'm trying to fix a bug in Gadfly (GiovineItalia/Gadfly.jl#844) and one of things I'm running into is the lack of a distinguishable_colors for the ColorAlpha type:

ERROR: MethodError: no method matching distinguishable_colors(::Int64, ::Array{ColorTypes.RGBA{Float64},1})
Closest candidates are:
  distinguishable_colors(::Integer; kwargs...) at /Users/tamasnagy/.julia/v0.5/Colors/src/colormaps.jl:86
  distinguishable_colors{T<:ColorTypes.Color{T,N}}(::Integer, ::AbstractArray{T<:ColorTypes.Color,1}; transform, lchoices, cchoices, hchoices) at /Users/tamasnagy/.julia/v0.5/Colors/src/colormaps.jl:39
  distinguishable_colors(::Integer, ::ColorTypes.Color{T,N}; kwargs...) at /Users/tamasnagy/.julia/v0.5/Colors/src/colormaps.jl:85

Would it enough to store the transparency values, run distinguishable_colors and add the transparency values back in?

Color comparison allocates memory in 0.3

const transparent_color = RGBA{Ufixed8}(0.0,0.0,0.0,0.0)
function count_trans(arr)
    out::Int = 0
    for a in arr
        if a == transparent_color out += 1 end
        #if a.r == transparent_color.r && a.g == transparent_color.g && a.b == transparent_color.b
        #    out += 1 end
    end
    out
end
arr = fill(transparent_color, 1000000)
@time count_trans(arr)
> elapsed time: 0.031248975 seconds (12273160 bytes allocated)

The commented out version allocates 33 KB. The work-around is easy for me, so I'm not asking for a fix, more of a FYI. Is that useful? I need to bite the bullet and figure out how to contribute soon, I think I can fix that myself.

If it's fixed in 0.4 it might push me to upgrade before the release.

Graceful parsing of Colorants

This isn't ideal behavior:

julia> using Colors

julia> parse(Colorant, "red")
RGB{U8}(1.0,0.0,0.0)

julia> parse(Colorant, colorant"red")
ERROR: StackOverflowError:
 in parse at /home/tom/.julia/v0.4/Colors/src/parse.jl:136 (repeats 342 times)

Should there be a better signature in parse:

Base.parse{C<:Colorant}(::Type{C}, desc::AbstractString) = convert(C, parse(Colorant, desc))::C

and/or should there be a "pass-through" option for Colorants:

Base.parse{C<:Colorant}(::Type{C}, c::Colorant) = convert(C, c)

Support for CMYK colorspaces

This is by no means a big issue but I am curious to know if there are any plans for adding CMYK as a color type. I realise that this might be a lot of work since ICC color profiles would need to be used for proper CMYK conversion.

Limit for displaying vector of colors in IJulia

When trying to display large vectors of Colors (for example when you have a long row of pixels from Images.jl) in IJulia, there should be a default limit for when the display gets rendered as a PNG rather than an SVG. For large vectors and slow computers (or computers with not that much RAM), displaying a 1000-point vector in an SVG in IJulia bricks the computer.

colormap breaking on 0.3

Hi,

I noticed this when my Travis build for ThreeJS.jl failed. Reproduced locally by using Julia 0.3.11 and Colors v0.5.3. I tried Pkg.checkout("Colors") also to no avail.

               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "help()" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.3.11 (2015-07-27 06:18 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-apple-darwin13.4.0

julia> using Colors

julia> colormap("RdBu")
ERROR: type cannot be constructed
 in mix_linearly at /Users/rohitvarkey/.julia/v0.3/Colors/src/colormaps.jl:132
 in sequential_palette at /Users/rohitvarkey/.julia/v0.3/Colors/src/colormaps.jl:152
 in diverging_palette at /Users/rohitvarkey/.julia/v0.3/Colors/src/colormaps.jl:225
 in colormap at /Users/rohitvarkey/.julia/v0.3/Colors/src/colormaps.jl:282
 in colormap at /Users/rohitvarkey/.julia/v0.3/Colors/src/colormaps.jl:256

Bradford transformation support

As README.md says, Colors.jl already has a useful function for chromatic adaptation named whitebalance.
whitebalance uses the CAT02 transformation matrix to convert colors into LMS.
However, not only the CAT02 but also the linear Bradford transformation is commonly used in the field of color management because of the interoperability.
In fact, to minimize the risk of conflict, the Bradford model is recommended in the ICC specification.

We can obtain the adaptation result in the Bradford model by converting the colors into LMS with the Bradford transformation in advance of calling whitebalance, and converting the result back into the original color space.
I think it's too much bother to do that every time, though.

A simple solution is to add a new function such as the following:

# the Bradford transformation matrix from v4 ICC Specification
const BFD = [ 0.8951  0.2664 -0.1614
             -0.7502  1.7135  0.0367
              0.0389 -0.0685  1.0296 ]
const BFD_INV = inv(BFD)

function bradford{T <: Color}(c::T, src_white::Color, ref_white::Color)
    c_xyz = convert(XYZ, c)
    src_xyz = convert(XYZ, src_white)
    dest_xyz = convert(XYZ, ref_white)
    
    c_lms = BFD * [c_xyz.x, c_xyz.y, c_xyz.z]
    src_wp = BFD * [src_xyz.x, src_xyz.y, src_xyz.z]
    dest_wp = BFD * [dest_xyz.x, dest_xyz.y, dest_xyz.z]
    ans = BFD_INV * (c_lms .* dest_wp ./ src_wp)

    convert(T, XYZ(ans[1], ans[2], ans[3]))
end

But I don't know whether it makes sense to propose such an ad-hoc function.

Another solution is to make changes to cnvt{T}(::Type{LMS{T}}, c::XYZ) and whitebalance to take the CAT matrix as an optional argument.

Do you have any ideas?

Generate seed for distinguishable_colors

As part of Plots, I let the user specify both a background color and series colors. Defaults are colorant"white" for the background and ':auto' for the series colors. Right now for :auto I choose from this pre-generated list:

const COLORS = distinguishable_colors(20)

However it would be ideal if those colors could be chosen on-the-fly, to be distiguishable both from the background color and other previous colors (i.e. not a hardcoded 20-length vector). This way if I choose a black background, I don't plot a black line as the default.

Does this exist within Colors? I feel like the pieces are there, I'm just not sure the right way to access them.

Please consider deleting Project.toml

It is not yet needed as REQUIRE is the basis for the registry and, for the time being, the Project.toml file breaks CIBot for all packages that depend on Colors. That will be fixed eventually but meanwhile, it would be great if you could remove the project file.

The 3-digit RGB notation (#rgb) is converted incorrectly

According to the CSS specification or SVG specification, the three-digit RGB notation (#rgb) is converted into six-digit form (#rrggbb) by replicating digits, not by adding zeros.

However, the current implementation (v0.7.3) incorrectly interprets the #rgb.

julia> colorant"#fb0" == colorant"#f0b000" # adding zeros
true

julia> colorant"#fb0" == colorant"#ffbb00" # replicating digits
false

This problem may be corrected by changing the scaling factor 16 to 17.

Question: Interface for external colormaps?

Would it make sense to have a general interface to colormaps via Colors? So to have in Colors something like: register_colormap(cname, function) that attaches a function to create colormaps (like 'jet') to the Colors API, so that colormap('jet',64) produces something?

WARNING: convert(::Type{UInt32},c::ColorTypes.RGB24) is deprecated

i'm using this:

z = zeros(UInt32,2,2)
c1 = convert(RGB24,colorant"grey20")
c2 = convert(RGB24,colorant"grey80")
z[1,1] = c1
z[1,2] = c2
z[2,1] = c2
z[2,2] = c1

to fill a small bitmap. This works, but gets the warning

WARNING: convert(::Type{UInt32},c::ColorTypes.RGB24) is deprecated, use reinterpret(UInt32,c) instead.
 in depwarn(::String, ::Symbol) at ./deprecated.jl:64
 in convert(::Type{UInt32}, ::ColorTypes.RGB24) at ./deprecated.jl:50
 in setindex!(::Array{UInt32,2}, ::ColorTypes.RGB24, ::Int64, ::Int64) at ./array.jl:416
 in include_from_node1(::String) at ./loading.jl:488
 in eval(::Module, ::Any) at ./boot.jl:234
 in eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
 in macro expansion at ./REPL.jl:95 [inlined]
 in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68
while loading /home/lobi/juliarepo/colconv.jl, in expression starting on line 4

so line 4 is the assignment of the color(value) to UInt32.
I could use

c1 = reinterpret(UInt32,convert(RGB24,colorant"grey20"))

but i'm not sure...
Is the correct reinterpretation is just missing from the convertions.jl ?

Example sequential_palette

Hello,

I'm having some troubles generating a sequential_palette for a heat map. The documentation is not clear to me. Can someone provide me with a working example of sequential_palette and diverging_palette? Can I use this with a heatmap in Plots.jl?

sequential_palette(h, [N::Int=100; c=0.88, s=0.6, b=0.75, w=0.15, d=0.0, wcolor=RGB(1,1,0), 
dcolor=RGB(0,0,1), logscale=false])

diverging_palette(h1, h2 [, N::Int=100; mid=0.5,c=0.88, s=0.6, b=0.75, w=0.15, d1=0.0, d2=0.0,
 wcolor=RGB(1,1,0), dcolor1=RGB(1,0,0), dcolor2=RGB(0,0,1), logscale=false])

Broken distinguishable_colors

When allowing for high luminances it produces undistinguishable colors :(

using Colors
Colors.distinguishable_colors(8, lchoices=linspace(0, 255, 5))

image

In comparison the behaviour from the old Color.jl package.

using Color
Color.distinguishable_colors(8, lchoices=linspace(0, 255, 5))

image

Happens with both, Colors release and master.

using Colors gives LoadError: Failed to precompile Colors

INFO: Precompiling module Colors.
ERROR: LoadError: LoadError: MethodError: no method matching rem(::Int64, ::Type{FixedPointNumbers.UFixed{UInt8,8}})
Closest candidates are:
  rem(::Int64, !Matched::Type{Int8}) at int.jl:208
  rem(::Int64, !Matched::Type{Int16}) at int.jl:208
  rem(::Int64, !Matched::Type{Int32}) at int.jl:208
  ...
 in ColorTypes.RGB{FixedPointNumbers.UFixed{UInt8,8}}(::Int64, ::Int64, ::Int64) at /Users/edelman/.julia/v0.5/ColorTypes/src/types.jl:91
 in ColorTypes.RGB{T<:Union{AbstractFloat,FixedPointNumbers.FixedPoint}}(::Int64, ::Int64, ::Int64) at /Users/edelman/.julia/v0.5/ColorTypes/src/types.jl:437
 in include_from_node1(::String) at ./loading.jl:488
 in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 in include_from_node1(::String) at ./loading.jl:488
 in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 in macro expansion; at ./none:2 [inlined]
 in anonymous at ./<missing>:?
 in eval(::Module, ::Any) at ./boot.jl:234
 in eval(::Module, ::Any) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 in process_options(::Base.JLOptions) at ./client.jl:239
 in _start() at ./client.jl:318
 in _start() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
while loading /Users/edelman/.julia/v0.5/Colors/src/algorithms.jl, in expression starting on line 66
while loading /Users/edelman/.julia/v0.5/Colors/src/Colors.jl, in expression starting on line 28
LoadError: Failed to precompile Colors to /Users/edelman/.julia/lib/v0.5/Colors.ji.
while loading In[1], in expression starting on line 1

 in compilecache(::String) at ./loading.jl:593
 in require(::Symbol) at ./loading.jl:422
 in require(::Symbol) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?

Type stability regression for `mean(::Array{RGB{N0f8}})` from 0.6 to 0.7

I don't know where the isssue was introduced exactly (or where this issue should be opened), but it seems to occur in Base._mapreduce(identity, Base.add_sum, ...) somewhere.

0.6

julia> using Colors, ColorVectorSpace, FixedPointNumbers

julia> A = rand(RGB{N0f8}, 2, 2)
2ร—2 Array{ColorTypes.RGB{FixedPointNumbers.Normed{UInt8,8}},2}:
 RGB{N0f8}(0.71,0.686,0.294)   RGB{N0f8}(0.871,0.322,0.667)
 RGB{N0f8}(0.369,0.055,0.478)  RGB{N0f8}(0.016,0.035,0.533)

julia> Test.@inferred mean(A)
RGB{Float64}(0.4911764705882353,0.27450980392156865,0.4931372549019607)

0.7

julia> using Colors, ColorVectorSpace, FixedPointNumbers, Statistics, Test

julia> A = rand(RGB{N0f8}, 2, 2)
2ร—2 Array{RGB{N0f8},2} with eltype RGB{Normed{UInt8,8}}:
 RGB{N0f8}(0.188,0.757,0.051)  RGB{N0f8}(0.922,0.871,0.012)
 RGB{N0f8}(0.62,0.184,0.69)    RGB{N0f8}(0.863,0.498,0.675)

julia> Test.@inferred mean(A)
ERROR: return type RGB{Float64} does not match inferred return type Union{RGB{Float32}, RGB{Float64}}
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] top-level scope at none:0

Colormaps are missing

Thanks for this great works. One thing I would like to add. As compared to Matlab, there are many missing built-in colormaps. It would be very convenient for users if a similar lists of Matlab's colormaps is provided in this package.

Viridis colormap in Colors.jl

colors = colormap("Blues", 10) is very useful for Gadfly, but it requires a non-white background for my plots for when the color is white.
As a feature request, it would be great to have the new Viridis colormap in Colors.jl that maps a scalar value between 0 and 1 to a color!

https://bids.github.io/colormap/

convert RGB{Float16} -> HSI sometimes fails

most of the time there is no problem, but if I try to convert RGB{Float16}(0.9473,0.962,0.9766) to HSI I run into an DomainError.

convert(HSI,RGB{Float16}(0.9473,0.962,0.9766))
ERROR: DomainError:
 in cnvt(::Type{ColorTypes.HSI{Float16}}, ::ColorTypes.RGB{Float16}) at ~/.julia/v0.5/Colors/src/conversions.jl:258
 in convert(::Type{ColorTypes.HSI}, ::ColorTypes.RGB{Float16}) at ~/.julia/v0.5/ColorTypes/src/conversions.jl:7

This Error does not occur if Float32 or Float64 is used instead of Float16. Furthermore the Error just occurs for some RGB values and not for all. This behaviour seems odd to me.

Julia 0.6 TODO: write awesome promotion rules

Between ColorTypes and #272, we have some useful but imperfect promotion rules that I propose to fix once we can rely on the awesome new type system. Here's one simple example of current failings:

julia> using ColorTypes

julia> promote_type(RGB1{Float32}, RGB1{Float32})
ColorTypes.RGB1{Float32}

julia> promote_type(RGB1{Float32}, RGB1{Float64})
ColorTypes.RGB{Float64}

This behavior is a consequence of these rules. The ideal way to write this would be to separately promote the "inner" type (Float32 or Float64) and the "outer" type (e.g., RGB1{<:Fractional}). I suffered through doing something similar with conversion (e.g., convert(RGB, c) without specifying the "inner" type) on julia 0.4, and it wasn't fun: getting the dispatch working properly for types with only a typevar inner type was basically black art and strongly dependent on the order of function definitions. I basically don't have the time/patience to do this again. But once we can rely on the new type system, this should be much more pleasant.

Named colors shouldn't be Tuple{Int64,Int64,Int64}

Hello,

I noticed

julia> Colors.color_names["indianred"]
(205, 92, 92)

julia> typeof(Colors.color_names["indianred"])
Tuple{Int64,Int64,Int64}

that's odd... I wonder why it is not Tuple{UInt8,UInt8,UInt8}

maybe a better approach could be to have RGB{N0f8} as value in color_names dictionnary.

Or provide function to get color as RGB{N0f8}

using Colors
using ColorTypes
using FixedPointNumbers


struct NamedColor
    s::String
end

function RGB{T}(namedcolor::NamedColor) where {T}
    RGB(map(c->reinterpret(T, c), UInt8.(Colors.color_names[namedcolor.s]))...)
end

RGB(namedcolor::NamedColor) = RGB{N0f8}(namedcolor)

namedcolor = NamedColor("indianred")

println(RGB{N0f8}(namedcolor))
println(RGB(namedcolor))

Maybe having some other function to return any RGB{T} from NamedColor should be considered.

Kind regards

Method ambiguity warnings with Interact

Colors v0.5.2 and Interact v0.1.6 seem to now have ambiguous definitions for parse. Not sure where the fix should go.

cc: @shashi

Warning: New definition 
    parse(Type{C<:Colorant{T,N}},Any) at /Users/aviks/.julia/v0.3/Colors/src/parse.jl:136
is ambiguous with: 
    parse(Any,Textbox{T<:Number}) at /Users/aviks/.julia/v0.3/Interact/src/widgets.jl:109.
To fix, define 
    parse(Type{C<:Colorant{T,N}},Textbox{T<:Number})
before the new definition.
Warning: New definition 
    parse(Type{C<:Colorant{T,N}},Any) at /Users/aviks/.julia/v0.3/Colors/src/parse.jl:136
is ambiguous with: 
    parse(Any,InputWidget{Bool}) at /Users/aviks/.julia/v0.3/Interact/src/Interact.jl:40.
To fix, define 
    parse(Type{C<:Colorant{T,N}},InputWidget{Bool})
before the new definition.
Warning: New definition 
    parse(Type{C<:Colorant{T,N}},Any) at /Users/aviks/.julia/v0.3/Colors/src/parse.jl:136
is ambiguous with: 
    parse(Any,InputWidget{T<:Integer}) at /Users/aviks/.julia/v0.3/Interact/src/Interact.jl:38.
To fix, define 
    parse(Type{C<:Colorant{T,N}},InputWidget{T<:Integer})
before the new definition.
Warning: New definition 
    parse(Type{C<:Colorant{T,N}},Any) at /Users/aviks/.julia/v0.3/Colors/src/parse.jl:136
is ambiguous with: 
    parse(Any,InputWidget{T<:FloatingPoint}) at /Users/aviks/.julia/v0.3/Interact/src/Interact.jl:39.
To fix, define 
    parse(Type{C<:Colorant{T,N}},InputWidget{T<:FloatingPoint})
before the new definition.
Warning: New definition 
    parse(Type{C<:Colorant{T,N}},Any) at /Users/aviks/.julia/v0.3/Colors/src/parse.jl:136
is ambiguous with: 
    parse(Any,InputWidget{T}) at /Users/aviks/.julia/v0.3/Interact/src/Interact.jl:33.
To fix, define 
    parse(Type{C<:Colorant{T,N}},InputWidget{T})
before the new definition.

Failed to precompile Colors on recent 0.7dev

with a Colors 0.8.2 on 0.7.0-DEV.3183

julia> Pkg.test("Colors")
I- Computing test dependencies for Colors... -Info:Base.Pkg.Entry:entry.jl:707
I- Installing JLD2 v0.0.4 -Info:Base.Pkg.Entry:entry.jl:537
I- Testing Colors -Info:Base.Pkg.Entry:entry.jl:717
WARNING: importing deprecated binding Base.@sprintf into Colors.
ERROR: LoadError: LoadError: LoadError: LoadError: Base.@sprintf has been moved to the standard library package Printf.
Restart Julia and then run `using Printf` to load it.
Stacktrace:
 [1] error(::Function, ::String, ::String, ::String, ::String, ::String, ::String) at ./error.jl:42
 [2] #@sprintf#919(::NamedTuple{(),Tuple{}}, ::Function, ::LineNumberNode, ::Vararg{Any,N} where N) at ./deprecated.jl:138
 [3] @sprintf(::Vararg{Any,N} where N) at ./deprecated.jl:138
 [4] #macroexpand#37 at ./expr.jl:75 [inlined]
 [5] macroexpand at ./expr.jl:74 [inlined]
 [6] docm(::LineNumberNode, ::Module, ::String, ::Expr, ::Bool) at ./docs/Docs.jl:657 (repeats 2 times)
 [7] @doc(::LineNumberNode, ::Module, ::String, ::Vararg{Any,N} where N) at ./boot.jl:411
 [8] include at ./boot.jl:295 [inlined]
 [9] include_relative(::Module, ::String) at ./loading.jl:503
 [10] include at ./sysimg.jl:26 [inlined]
 [11] include(::String) at /home/lobi/.julia/v0.7/Colors/src/Colors.jl:3
 [12] top-level scope
 [13] include at ./boot.jl:295 [inlined]
 [14] include_relative(::Module, ::String) at ./loading.jl:503
 [15] include(::Module, ::String) at ./sysimg.jl:26
 [16] top-level scope
 [17] eval at ./boot.jl:298 [inlined]
 [18] top-level scope at ./<missing>:2
in expression starting at /home/lobi/.julia/v0.7/Colors/src/utilities.jl:19
in expression starting at /home/lobi/.julia/v0.7/Colors/src/utilities.jl:12
in expression starting at /home/lobi/.julia/v0.7/Colors/src/utilities.jl:12
in expression starting at /home/lobi/.julia/v0.7/Colors/src/Colors.jl:30
ERROR: LoadError: Failed to precompile Colors to /home/lobi/.julia/lib/v0.7/Colors.ji.
Stacktrace:
 [1] error at ./error.jl:33 [inlined]
 [2] compilecache(::String) at ./loading.jl:630
 [3] compilecache at ./loading.jl:587 [inlined]
 [4] _require(::Symbol) at ./loading.jl:442
 [5] require(::Symbol) at ./loading.jl:315
 [6] include at ./boot.jl:295 [inlined]
 [7] include_relative(::Module, ::String) at ./loading.jl:503
 [8] include(::Module, ::String) at ./sysimg.jl:26
 [9] process_options(::Base.JLOptions) at ./client.jl:330
 [10] _start() at ./client.jl:381
in expression starting at /home/lobi/.julia/v0.7/Colors/test/runtests.jl:1
E- ------------------------------------------------------------
|  # Testing failed for Colors
|   -Error:Base.Pkg.Entry:entry.jl:733
|  exception = ErrorException("failed process: Process(`/home/lobi/julia07/usr/bin/julia -Cnative -J/home/lobi/julia07/usr/lib/julia/sys.so --compile=yes --depwarn=yes --code-coverage=none --color=yes --compiled-modules=yes --check-bounds=yes --warn-overwrite=yes --startup-file=yes /home/lobi/.julia/v0.7/Colors/test/runtests.jl`, ProcessExited(1)) [1]")
I- Removing JLD2 v0.0.4 -Info:Base.Pkg.Entry:entry.jl:540
ERROR: Colors had test errors

Change permissions

Could someone change the permissions on this repo? I keep accidentally pushing directly to master when I forget to branch...

Fix show() method to reshape a copy

Per discussion in Slack with @pfitzseb in #juno-bridged on slack, there's an issue with the show() method that causes weird errors in Juno. He suggested that this line should instead be:

show(io, MIME"image/svg+xml"(), reshape(copy(cs), (1, length(cs))))

Some color names are missing

The following parsing of colors fails because color_names is missing some color names in
SVG color keywords.

colorant"aqua"   # "aqua"   => (  0, 255, 255),
colorant"indigo" # "indigo" => ( 75,   0, 130),
colorant"lime"   # "lime"   => (  0, 255,   0),
colorant"teal"   # "teal"   => (  0, 128, 128),

`colordiff` and perceptual difference

I have a hard time interpreting the perceptual difference coming out of colordiff. Here is an example - I tried to work out which of the ANSI terminal colors come closest to any julia color, using colordiff. This is when I try to match e.g. a dusty blue:

using Colors, Plots
gr(legend = false, grid = false, ms = 10, msw = 0)

# the ANSI colors (minus the 16 first which are duplicates)
hexcodes = parse.([Colorant], ["#000000", "#00005f", "#000087", "#0000af", "#0000d7", "#0000ff", "#005f00", "#005f5f", "#005f87", "#005faf", "#005fd7", "#005fff", "#008700", "#00875f", "#008787", "#0087af", "#0087d7", "#0087ff", "#00af00", "#00af5f", "#00af87", "#00afaf", "#00afd7", "#00afff", "#00d700", "#00d75f", "#00d787", "#00d7af", "#00d7d7", "#00d7ff", "#00ff00", "#00ff5f", "#00ff87", "#00ffaf", "#00ffd7", "#00ffff", "#5f0000", "#5f005f", "#5f0087", "#5f00af", "#5f00d7", "#5f00ff", "#5f5f00", "#5f5f5f", "#5f5f87", "#5f5faf", "#5f5fd7", "#5f5fff", "#5f8700", "#5f875f", "#5f8787", "#5f87af", "#5f87d7", "#5f87ff", "#5faf00", "#5faf5f", "#5faf87", "#5fafaf", "#5fafd7", "#5fafff", "#5fd700", "#5fd75f", "#5fd787", "#5fd7af", "#5fd7d7", "#5fd7ff", "#5fff00", "#5fff5f", "#5fff87", "#5fffaf", "#5fffd7", "#5fffff", "#870000", "#87005f", "#870087", "#8700af", "#8700d7", "#8700ff", "#875f00", "#875f5f", "#875f87", "#875faf", "#875fd7", "#875fff", "#878700", "#87875f", "#878787", "#8787af", "#8787d7", "#8787ff", "#87af00", "#87af5f", "#87af87", "#87afaf", "#87afd7", "#87afff", "#87d700", "#87d75f", "#87d787", "#87d7af", "#87d7d7", "#87d7ff", "#87ff00", "#87ff5f", "#87ff87", "#87ffaf", "#87ffd7", "#87ffff", "#af0000", "#af005f", "#af0087", "#af00af", "#af00d7", "#af00ff", "#af5f00", "#af5f5f", "#af5f87", "#af5faf", "#af5fd7", "#af5fff", "#af8700", "#af875f", "#af8787", "#af87af", "#af87d7", "#af87ff", "#afaf00", "#afaf5f", "#afaf87", "#afafaf", "#afafd7", "#afafff", "#afd700", "#afd75f", "#afd787", "#afd7af", "#afd7d7", "#afd7ff", "#afff00", "#afff5f", "#afff87", "#afffaf", "#afffd7", "#afffff", "#d70000", "#d7005f", "#d70087", "#d700af", "#d700d7", "#d700ff", "#d75f00", "#d75f5f", "#d75f87", "#d75faf", "#d75fd7", "#d75fff", "#d78700", "#d7875f", "#d78787", "#d787af", "#d787d7", "#d787ff", "#d7af00", "#d7af5f", "#d7af87", "#d7afaf", "#d7afd7", "#d7afff", "#d7d700", "#d7d75f", "#d7d787", "#d7d7af", "#d7d7d7", "#d7d7ff", "#d7ff00", "#d7ff5f", "#d7ff87", "#d7ffaf", "#d7ffd7", "#d7ffff", "#ff0000", "#ff005f", "#ff0087", "#ff00af", "#ff00d7", "#ff00ff", "#ff5f00", "#ff5f5f", "#ff5f87", "#ff5faf", "#ff5fd7", "#ff5fff", "#ff8700", "#ff875f", "#ff8787", "#ff87af", "#ff87d7", "#ff87ff", "#ffaf00", "#ffaf5f", "#ffaf87", "#ffafaf", "#ffafd7", "#ffafff", "#ffd700", "#ffd75f", "#ffd787", "#ffd7af", "#ffd7d7", "#ffd7ff", "#ffff00", "#ffff5f", "#ffff87", "#ffffaf", "#ffffd7", "#ffffff", "#080808", "#121212", "#1c1c1c", "#262626", "#303030", "#3a3a3a", "#444444", "#4e4e4e", "#585858", "#626262", "#6c6c6c", "#767676", "#808080", "#8a8a8a", "#949494", "#9e9e9e", "#a8a8a8", "#b2b2b2", "#bcbcbc", "#c6c6c6", "#d0d0d0", "#dadada", "#e4e4e4", "#eeeeee"])

#our dusty blue
blue = parse(Colorant, "#7aa6da")
cd = colordiff.([blue], hexcodes)
scatter(cd, color = hexcodes)
scatter!([123], [-3], color = blue)

skaermbillede 2017-04-27 kl 11 33 24

Now the y axis should delimit how close they are perceptually to our focal color, which is placed at the very bottom. Perceptually, I see lots of colors with colordiff values above 25 that are perceptually much more similar to the bottom point than many of the very bottom ones.
Is there something wrong with the colordiff function (or is it my eyes?).

I experimented with DE_AB() and DE_94() but it did not appear to make a huge difference.

Thanks!

Documenter docs needs testing

I moved the readme information into Documenter format. There's a few docstrings which could be added to the code at some point.

unexpected results inconvert RGB -> [DIN99d,DIN99dA,ADIN99d] -> RGB

Normally, I would expect that the conversion c1::TypeA -> c2::TypeB -> c3::TypeA yields that c1 is approximately equal to c3. However for the types above one gets

julia> convert(RGB,convert(DIN99d,RGB(1,0.5,0)))
RGB{Float64}(0.5618900556828353,0.660676085072947,0.6265900923320097)

julia> convert(RGBA,convert(DIN99dA,RGBA(1,0.5,0,0.4)))
RGBA{Float64}(0.5618900556828353,0.660676085072947,0.6265900923320097,0.4)

which suggests, that there is a problem with the conversion RGB<->DIN99d.

RGBA and InexactError

I'm sure this makes sense programmatically:

julia> RGBA(56, 34, 23)
ERROR: InexactError()
 in ColorTypes.RGBA{T<:Union{AbstractFloat,FixedPointNumbers.FixedPoint}}(::Int64, 
 ::Int64, ::Int64) at /Users/me/.julia/v0.5/ColorTypes/src/types.jl:423

julia> RGBA(56., 34, 23)
RGBA{Float64}(56.0,34.0,23.0,1.0)

but it's not very user-friendly... It would be nice if there was a fallback so that 56 was treated as 56..

Colours 0.6.6, Julia Version 0.5.0-rc4+0

[a,b] concatenation is deprecated

I'm seeing loads of these (my terminal's overflowing with warnings...:)):

WARNING: [a,b] concatenation is deprecated; use [a;b] instead
 in depwarn at /Applications/Julia-0.4.0.app/Contents/Resources/julia/lib/julia/sys.dylib
 in oldstyle_vcat_warning at /Applications/Julia-0.4.0.app/Contents/Resources/julia/lib/julia/sys.dylib
 in diverging_palette at /Users/cormullion/.julia/v0.4/Colors/src/colormaps.jl:234
 in include at /Applications/Julia-0.4.0.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at /Applications/Julia-0.4.0.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include at /Applications/Julia-0.4.0.app/Contents/Resources/julia/lib/julia/sys.dylib
 in include_from_node1 at /Applications/Julia-0.4.0.app/Contents/Resources/julia/lib/julia/sys.dylib

I think it's here:

if isodd(N)
    midcol = weighted_color_mean(0.5, pal1[end], pal2[1])
    return [pal1[1:end-1]; midcol; pal2[2:end]]
else
    return [pal1[1:end-1]; pal2[2:end]]
end

What's the fix - return collect(pal1[1:end-1]; midcol; pal2[2:end])?

Precompilation fails: `N0f8 not defined`

With v0.7 (julia v0.5), here's the full error message:

INFO: Precompiling module Colors.
ERROR: LoadError: LoadError: UndefVarError: N0f8 not defined
 in include_from_node1(::String) at .\loading.jl:488 (repeats 2 times)
 in macro expansion; at .\none:2 [inlined]
 in anonymous at .\<missing>:?
 in eval(::Module, ::Any) at .\boot.jl:234
 in process_options(::Base.JLOptions) at .\client.jl:239
 in _start() at .\client.jl:318
while loading C:\Users\cbinz\.julia\v0.5\Colors\src\conversions.jl, in expression starting on line 170
while loading C:\Users\cbinz\.julia\v0.5\Colors\src\Colors.jl, in expression starting on line 29
ERROR: Failed to precompile Colors to C:\Users\cbinz\.julia\lib\v0.5\Colors.ji.
 in compilecache(::String) at .\loading.jl:593
 in require(::Symbol) at .\loading.jl:422
 in _include_from_serialized(::String) at .\loading.jl:150
 in _require_from_serialized(::Int64, ::Symbol, ::String, ::Bool) at .\loading.jl:187
 in _require_search_from_serialized(::Int64, ::Symbol, ::String, ::Bool) at .\loading.jl:217
 in require(::Symbol) at .\loading.jl:371

late/lazy evaluation of colorant" string?

julia> using Colors

julia> c = colorant"red4"
RGB{U8}(0.545,0.0,0.0)

julia> c
RGB{U8}(0.545,0.0,0.0)

julia> v = v"0.4.1"
v"0.4.1"

julia> v
v"0.4.1"

colors are immediately converted from colorant, and so from the moment of conversion on only show up as numbers - while the colorname would be more interesting.
Counterexample is (might be) the version string, which is always displayed as string.

Could a late/lazy evaluation of colorant" be done?

First example in README doesn't work

Which, annoyingly, is exactly what I wanted to do:

julia> convert(RGB, HSL(270, 0.5, 0.5))
ERROR: No conversion of HSL{Float64}(270.0,0.5,0.5) to ColorTypes.RGB{Float64} has been defined
 in convert(::Type{ColorTypes.RGB}, ::ColorTypes.HSL{Float64}) at /Users/simon/.julia/v0.5/ColorTypes/src/conversions.jl:7

Better aspect ratio preservation when displaying as SVG

I've noticed some minor weirdness with the aspect ratio of arrays of Colors when displayed as SVG, and I think that some improvement might be possible. The relevant code is here: https://github.com/JuliaGraphics/Colors.jl/blob/master/src/display.jl#L22

The specific set of checks in that code can lead to some very strange edge cases. For example, try creating the following arrays:

A = zeros(Gray, 9, 10)
B = zeros(Gray, 9, 18)
C = zeros(Gray, 9, 19)

Matrix A renders each color as a perfect square, which is great. Matrix B squashes the aspect ratio slightly, so each rectangle is a bit taller than it is wide. Matrix C, however, results in this:

screen shot 2017-04-06 at 1 40 26 pm

That is, the resulting array is taller than it is wide, and each rectangle has been dramatically stretched. That seems like the wrong behavior.

I realize that this is a weird edge case, but it happened to come up in my work, so I figured I'd report it.

If I may, I'd propose something like the following:

  1. compute the natural aspect ratio of the array (m / n)
  2. clamp that aspect ratio to some pre-determined range of values
  3. size the rectangles based on that clamped aspect ratio
  4. scale the rectangles to obey the min. and max. limits on the output size

If that seems reasonable, I'm happy to work on this myself and submit a PR.

BTW @Evizero you mentioned something over in JuliaImages/Images.jl#619 about new code to render an image in a table. Is that a proposed replacement for the SVG code here?

Drop Graphics dependency

I don't know when or how this happened in Color.jl, but it seems really backwards. I guess it's a remnant from when Graphics.jl was in Base. I can do this, but I'll wait till after c-day.

does mid work on colormap?

I was playing with trying to change the midpoint in a colormap and it doesn't work the way I expected.

For example, colormap("Blues") generates an array that starts with

 RGB{Float64}(0.958129,0.992733,0.998897) 
 RGB{Float64}(0.948956,0.98958,0.997057)  
 RGB{Float64}(0.939677,0.986361,0.995234) 

and goes to

 RGB{Float64}(0.0548094,0.182609,0.382798)
 RGB{Float64}(0.0484511,0.169616,0.362331)
 RGB{Float64}(0.0418427,0.156645,0.341597)

with midpoint colormap("Blues")[50] giving:
RGB{Float64}(0.40043042841321896,0.7304593324507547,0.9058502694643216)
When I try colormap("Blues", mid=0.75)[50] I get the same result. I thought I should get something different because this point would move to the left. Do I misunderstand something?

Function or constructor to convert hex to Color object?

Is there any reason* that there isn't an inverse function for hex? That is, a way to convert hex triplets to a Color object. Something like:

Color("#7aa457")

or

Color(ihex("#7aa457"))

*A reason other than no one has implemented it. I ask because there might be some problems associated with the hex codes that I'm unaware of.

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.