Mix . install ( [
:hex_core ,
:explorer ,
:kino_explorer ,
:kino_vega_lite
] )
for app <- [ :hex_core , :inets , :ssl ] do
{ :ok , _apps } = Application . ensure_all_started ( app )
end
require Explorer.DataFrame
Explorer.DataFrame
config = :hex_core . default_config ( )
{ :ok , { 200 , _headers , result } } = :hex_repo . get_versions ( config )
[hex_http_httpc] using default ssl options which are insecure.
Configure your adapter with: {hex_http_httpc, #{http_options => [{ssl, SslOpts}]}}
{:ok,
{200,
%{
"accept-ranges" => "bytes",
"age" => "0",
"cache-control" => "public, max-age=3600",
"connection" => "keep-alive",
"content-length" => "263739",
"content-type" => "application/octet-stream",
"date" => "Tue, 03 Dec 2024 13:42:00 GMT",
"etag" => "\"18929c9d8d5a03dd64fcb862b4003b9c\"",
"last-modified" => "Tue, 03 Dec 2024 13:29:26 GMT",
"server" => "AmazonS3",
"via" => "1.1 varnish",
"x-amz-id-2" => "wELzuVelxrcTMksGuEjR5Opf50PkjpD0tNbHQLTQ43JIheD6NHxRYvKhMpWGhqIi5YpJhXehpHA=",
"x-amz-meta-surrogate-control" => "public, max-age=604800",
"x-amz-meta-surrogate-key" => "registry registry-index",
"x-amz-request-id" => "QX2AWD7S5R82XEHP",
"x-amz-server-side-encryption" => "AES256",
"x-amz-version-id" => "nfz3J9ulMFSB0gE8z7PcaPyKbZ8FF8RI",
"x-cache" => "MISS",
"x-cache-hits" => "0",
"x-served-by" => "cache-vie6345-VIE",
"x-timer" => "S1733233320.677303,VS0,VE526"
},
%{
packages: [
%{name: "a11y_audit", versions: ["0.1.0", "0.2.0", "0.2.1", "0.2.2"], retired: []},
%{name: "a_message", versions: ["1.0.0"], retired: []},
%{name: "aa", versions: ["0.1.0"], retired: []},
%{name: "aadya", versions: ["0.1.0"], retired: []},
%{name: "aasm", versions: ["0.1.0", "0.2.0"], retired: []},
%{name: "aatree", versions: ["0.1.0"], retired: []},
%{name: "aba", versions: ["0.1.0", "0.2.0", "0.3.0", "0.4.0"], retired: []},
%{name: "aba_api", versions: ["1.0.0"], retired: []},
%{name: "aba_cli", versions: ["1.0.0"], retired: []},
%{name: "aba_model", versions: ["1.0.0"], retired: []},
%{
name: "aba_validator",
versions: ["0.0.0", "0.1.2", "0.1.4", "1.0.0", "2.0.0", "2.1.0"],
retired: [0, 1]
},
%{
name: "abac",
versions: ["0.4.0", "0.10.0", "0.11.0", "0.11.1", "0.11.2", "0.11.3", "0.11.5", "1.7.0",
"1.7.1", "1.7.2", "1.8.0"],
retired: []
},
%{
name: "abacus",
versions: ["0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.3.2", "0.3.3", "0.4.0", "0.4.1", "0.4.2",
"2.0.0", "2.1.0"],
retired: []
},
%{name: "abacus_sm", versions: ["1.0.0"], retired: []},
%{name: "abacus_sql", versions: ["2.0.0", "2.1.0", "2.1.1"], retired: []},
%{name: "abatap", versions: ["0.1.0", "0.2.0"], retired: []},
%{name: "abbrev", versions: ["0.1.0"], retired: []},
%{name: "abc", versions: ["0.1.0"], retired: []},
%{name: "abex", versions: ["0.1.0", "0.1.1", "0.1.2"], retired: []},
%{
name: "abi",
versions: ["0.1.0", "0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7", "0.1.8",
"0.1.9", "0.1.10", "0.1.11", "0.1.12", "0.1.13", "0.1.15", "0.1.16", "0.1.17", "0.1.18",
"0.1.19", "0.1.20", "0.1.21-alpha1", "0.1.21-alpha2", ...],
retired: []
},
%{
name: "abit",
versions: ["0.1.0", "0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.2.0", "0.2.1", "0.2.2",
"0.2.3", "0.2.4", "0.3.0", "0.3.1", "0.3.2", "0.3.3"],
retired: []
},
%{name: "abnf", versions: ["0.0.1"], retired: []},
%{name: "abnf2", versions: ["0.1.2", "0.1.4"], retired: []},
%{
name: "abnf_parsec",
versions: ["0.1.0", "0.1.1", "0.1.2", "0.1.3", "1.0.0", "1.0.1", "1.1.0", "1.2.0", "1.2.1"],
retired: [4]
},
%{name: "abnfc", versions: ["0.5.2", "0.5.4"], retired: []},
%{
name: "about",
versions: ["0.0.1", "0.0.2", "0.0.3", "0.0.4", "0.0.5", "0.0.6", "0.0.7", "0.0.8", "0.0.9",
"0.0.10", "0.0.11"],
retired: []
},
%{
name: "absinthe",
versions: ["0.1.0", "0.2.1", "0.2.2", "0.2.3", "0.4.0", "0.4.1", "0.4.2", "0.4.3", "0.4.4",
"0.4.5", "0.4.6", "0.5.0", "0.5.1", "0.5.2", "1.0.0", ...],
retired: ~c"?e"
},
%{name: "absinthe_auth", versions: ["0.1.0", "0.1.1", "0.2.0", "0.2.1"], retired: []},
%{name: "absinthe_cache", versions: ["0.1.0"], retired: []},
%{name: "absinthe_cache_fairy", versions: ["0.2.0", "0.2.1", "0.2.2", "0.2.3"], retired: []},
%{name: "absinthe_client", versions: ["0.1.0", "0.1.1"], retired: []},
%{name: "absinthe_compose", versions: ["0.1.0"], retired: []},
%{name: "absinthe_conn_test", versions: ["0.0.0", "0.1.0", "0.1.1"], retired: []},
%{name: "absinthe_constraints", versions: ["0.0.1", "0.1.0", "0.1.1", "0.2.0"], retired: [0]},
%{name: "absinthe_ecto", versions: ["0.1.0", "0.1.1", "0.1.2", "0.1.3"], retired: []},
%{
name: "absinthe_error_payload",
versions: ["1.0.0", "1.0.1", "1.1.1", "1.1.2", "1.1.3", "1.1.4", ...],
retired: []
},
%{
name: "absinthe_extra",
versions: ["0.1.0", "0.1.1", "0.1.2", "0.1.3", "0.1.4", ...],
retired: []
},
%{
name: "absinthe_federation",
versions: ["0.1.0", "0.1.1", "0.1.2", "0.1.3", ...],
retired: []
},
%{name: "absinthe_field_telemetry", versions: ["0.1.0", "0.2.0", "0.2.1", ...], retired: []},
%{name: "absinthe_gen", versions: ["0.1.0", "0.1.1", ...], retired: []},
%{name: "absinthe_generator", versions: ["0.1.0", ...], retired: []},
%{name: "absinthe_graphql_ws", versions: [...], ...},
%{name: "absinthe_helpers", ...},
%{...},
...
],
repository: "hexpm"
}}}
df = result . packages
|> Explorer.DataFrame . new ( )
|> Explorer.DataFrame . explode ( :versions )
#Explorer.DataFrame<
Polars[121205 x 3]
name string ["a11y_audit", "a11y_audit", "a11y_audit", "a11y_audit", "a_message", ...]
retired list[s64] [[], [], [], [], [], ...]
versions string ["0.1.0", "0.2.0", "0.2.1", "0.2.2", "1.0.0", ...]
>
Version Count Distribution
summary_df = df
|> Explorer.DataFrame . group_by ( :name )
|> Explorer.DataFrame . summarise ( version_count: Explorer.Series . count ( versions ) )
|> Explorer.DataFrame . group_by ( :version_count )
|> Explorer.DataFrame . summarise ( package_count: Explorer.Series . count ( name ) )
|> Explorer.DataFrame . sort_by ( asc: version_count )
#Explorer.DataFrame<
Polars[140 x 2]
version_count u32 [1, 2, 3, 4, 5, ...]
package_count u32 [4791, 2672, 1803, 1287, 968, ...]
>
VegaLite . new ( width: 700 , height: 400 , title: "Version Count" )
|> VegaLite . data_from_values ( summary_df , only: [ "version_count" , "package_count" ] )
|> VegaLite . mark ( :line )
|> VegaLite . encode_field ( :x , "version_count" , type: :quantitative , scale: [ type: :log ] )
|> VegaLite . encode_field ( :y , "package_count" , type: :quantitative , scale: [ type: :log ] )
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"values":[{"package_count":4791,"version_count":1},{"package_count":2672,"version_count":2},{"package_count":1803,"version_count":3},{"package_count":1287,"version_count":4},{"package_count":968,"version_count":5},{"package_count":768,"version_count":6},{"package_count":587,"version_count":7},{"package_count":503,"version_count":8},{"package_count":405,"version_count":9},{"package_count":322,"version_count":10},{"package_count":290,"version_count":11},{"package_count":257,"version_count":12},{"package_count":221,"version_count":13},{"package_count":184,"version_count":14},{"package_count":171,"version_count":15},{"package_count":163,"version_count":16},{"package_count":115,"version_count":17},{"package_count":181,"version_count":18},{"package_count":99,"version_count":19},{"package_count":95,"version_count":20},{"package_count":77,"version_count":21},{"package_count":90,"version_count":22},{"package_count":76,"version_count":23},{"package_count":73,"version_count":24},{"package_count":56,"version_count":25},{"package_count":53,"version_count":26},{"package_count":33,"version_count":27},{"package_count":50,"version_count":28},{"package_count":36,"version_count":29},{"package_count":38,"version_count":30},{"package_count":32,"version_count":31},{"package_count":34,"version_count":32},{"package_count":16,"version_count":33},{"package_count":24,"version_count":34},{"package_count":10,"version_count":35},{"package_count":22,"version_count":36},{"package_count":27,"version_count":37},{"package_count":17,"version_count":38},{"package_count":19,"version_count":39},{"package_count":19,"version_count":40},{"package_count":20,"version_count":41},{"package_count":11,"version_count":42},{"package_count":14,"version_count":43},{"package_count":17,"version_count":44},{"package_count":13,"version_count":45},{"package_count":9,"version_count":46},{"package_count":14,"version_count":47},{"package_count":9,"version_count":48},{"package_count":15,"version_count":49},{"package_count":11,"version_count":50},{"package_count":13,"version_count":51},{"package_count":10,"version_count":52},{"package_count":4,"version_count":53},{"package_count":5,"version_count":54},{"package_count":9,"version_count":55},{"package_count":6,"version_count":56},{"package_count":10,"version_count":57},{"package_count":5,"version_count":58},{"package_count":7,"version_count":59},{"package_count":5,"version_count":60},{"package_count":9,"version_count":61},{"package_count":5,"version_count":62},{"package_count":11,"version_count":63},{"package_count":6,"version_count":64},{"package_count":8,"version_count":65},{"package_count":6,"version_count":66},{"package_count":4,"version_count":67},{"package_count":7,"version_count":68},{"package_count":5,"version_count":69},{"package_count":2,"version_count":70},{"package_count":4,"version_count":71},{"package_count":4,"version_count":72},{"package_count":5,"version_count":73},{"package_count":1,"version_count":74},{"package_count":5,"version_count":75},{"package_count":4,"version_count":76},{"package_count":1,"version_count":77},{"package_count":2,"version_count":78},{"package_count":3,"version_count":79},{"package_count":3,"version_count":80},{"package_count":2,"version_count":81},{"package_count":3,"version_count":82},{"package_count":2,"version_count":83},{"package_count":3,"version_count":84},{"package_count":6,"version_count":86},{"package_count":1,"version_count":87},{"package_count":3,"version_count":88},{"package_count":1,"version_count":89},{"package_count":3,"version_count":90},{"package_count":2,"version_count":92},{"package_count":2,"version_count":93},{"package_count":2,"version_count":96},{"package_count":2,"version_count":97},{"package_count":2,"version_count":98},{"package_count":1,"version_count":99},{"package_count":1,"version_count":100},{"package_count":3,"version_count":101},{"package_count":1,"version_count":102},{"package_count":1,"version_count":103},{"package_count":1,"version_count":105},{"package_count":1,"version_count":106},{"package_count":1,"version_count":107},{"package_count":2,"version_count":109},{"package_count":3,"version_count":110},{"package_count":2,"version_count":111},{"package_count":1,"version_count":112},{"package_count":2,"version_count":113},{"package_count":1,"version_count":115},{"package_count":1,"version_count":116},{"package_count":1,"version_count":119},{"package_count":1,"version_count":120},{"package_count":1,"version_count":123},{"package_count":1,"version_count":125},{"package_count":1,"version_count":127},{"package_count":2,"version_count":129},{"package_count":1,"version_count":130},{"package_count":1,"version_count":134},{"package_count":1,"version_count":136},{"package_count":1,"version_count":137},{"package_count":1,"version_count":138},{"package_count":1,"version_count":147},{"package_count":1,"version_count":148},{"package_count":1,"version_count":150},{"package_count":1,"version_count":151},{"package_count":1,"version_count":154},{"package_count":1,"version_count":162},{"package_count":1,"version_count":163},{"package_count":1,"version_count":165},{"package_count":2,"version_count":168},{"package_count":1,"version_count":178},{"package_count":1,"version_count":183},{"package_count":1,"version_count":192},{"package_count":1,"version_count":196},{"package_count":1,"version_count":201},{"package_count":1,"version_count":215},{"package_count":1,"version_count":258},{"package_count":1,"version_count":272},{"package_count":1,"version_count":288},{"package_count":1,"version_count":341},{"package_count":1,"version_count":744}]},"encoding":{"x":{"field":"version_count","scale":{"type":"log"},"type":"quantitative"},"y":{"field":"package_count","scale":{"type":"log"},"type":"quantitative"}},"height":400,"mark":"line","title":"Version Count","width":700}