using Gadlfy.jl and AlgebraOfGraphics.jl within same notebook causes MethodError - namespaces

I am making a Pluto notebook where I create the same simple plot with several plotting libraries. Since plotting libraries might define functions with the same name I work like this:
using AlgebraOfGraphics, RDatasets, CairoMakie
const AoG = AlgebraOfGraphics
iris = dataset("datasets", "iris")
iris_frequency = AoG.data(iris) *
AoG.mapping(:PetalLength, :PetalWidth) *
AoG.mapping(color = :Species)
AoG.draw(iris_frequency)
However, when I do using gadfly I get an error when calling AlgebraOfGraphics.draw(), and it is not clear to me why.
using Gadfly
AoG.draw(iris_frequency)
MethodError: no method matching size(::Compose.Property{Compose.FillPrimitive})
Closest candidates are:
size(!Matched::Union{LinearAlgebra.QR, LinearAlgebra.QRCompactWY, LinearAlgebra.QRPivoted}) at /opt/julia/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/qr.jl:524
size(!Matched::Union{LinearAlgebra.QR, LinearAlgebra.QRCompactWY, LinearAlgebra.QRPivoted}, !Matched::Integer) at /opt/julia/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/qr.jl:523
size(!Matched::Union{LinearAlgebra.Cholesky, LinearAlgebra.CholeskyPivoted}) at /opt/julia/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/cholesky.jl:442
...
axes #abstractarray.jl:89[inlined]
combine_axes(::Compose.Property{Compose.FillPrimitive}, ::Compose.Property{Compose.FillPrimitive}, ::Compose.Property{Compose.FillPrimitive})#broadcast.jl:483
shape(::AlgebraOfGraphics.Layer)#processing.jl:17
getlabeledarray(::AlgebraOfGraphics.Layer, ::Symbol)#processing.jl:72
(::AlgebraOfGraphics.var"#119#121"{Tuple{Symbol, Symbol}, AlgebraOfGraphics.Layer, Dict{Union{Int64, Symbol}, Any}})(::Int64)#processing.jl:100
ntuple#ntuple.jl:19[inlined]
mapkeys#entries.jl:75[inlined]
(::AlgebraOfGraphics.var"#118#120"{AlgebraOfGraphics.Layer, Dict{Union{Int64, Symbol}, Any}})(::Tuple{Symbol, Symbol})#processing.jl:99
map#tuple.jl:214[inlined]
process_mappings(::AlgebraOfGraphics.Layer)#processing.jl:98
to_entry(::AlgebraOfGraphics.Layer)#processing.jl:115
process(::AlgebraOfGraphics.Layer)#processing.jl:122
iterate#generator.jl:47[inlined]
collect(::Base.Generator{AlgebraOfGraphics.Layers, typeof(AlgebraOfGraphics.process)})#array.jl:678
map#abstractarray.jl:2323[inlined]
var"#compute_axes_grid#81"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::typeof(AlgebraOfGraphics.compute_axes_grid), ::Makie.Figure, ::AlgebraOfGraphics.Layer)#layers.jl:70
var"#plot!#90"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::typeof(Makie.plot!), ::Makie.Figure, ::AlgebraOfGraphics.Layer)#layers.jl:135
#plot#91#layers.jl:143[inlined]
var"#draw#92"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::typeof(AlgebraOfGraphics.draw), ::AlgebraOfGraphics.Layer)#layers.jl:150
draw(::AlgebraOfGraphics.Layer)#layers.jl:150
getlabeledarray(::AlgebraOfGraphics.Layer, ::Symbol)#processing.jl:72
(::AlgebraOfGraphics.var"#119#121"{Tuple{Symbol, Symbol}, AlgebraOfGraphics.Layer, Dict{Union{Int64, Symbol}, Any}})(::Int64)#processing.jl:100
ntuple#ntuple.jl:19[inlined]
mapkeys#entries.jl:75[inlined]
(::AlgebraOfGraphics.var"#118#120"{AlgebraOfGraphics.Layer, Dict{Union{Int64, Symbol}, Any}})(::Tuple{Symbol, Symbol})#processing.jl:99
map#tuple.jl:214[inlined]
top-level scope#Local: 7[inlined]process_mappings(::AlgebraOfGraphics.Layer)#processing.jl:98
to_entry(::AlgebraOfGraphics.Layer)#processing.jl:115
process(::AlgebraOfGraphics.Layer)#processing.jl:122
iterate#generator.jl:47[inlined]
collect(::Base.Generator{AlgebraOfGraphics.Layers, > typeof(AlgebraOfGraphics.process)})#array.jl:678
map#abstractarray.jl:2323[inlined]
var"#compute_axes_grid#81"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::typeof(AlgebraOfGraphics.compute_axes_grid), ::Makie.Figure, ::AlgebraOfGraphics.Layer)#layers.jl:70
var"#plot!#90"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::typeof(Makie.plot!), ::Makie.Figure, ::AlgebraOfGraphics.Layer)#layers.jl:135
#plot#91#layers.jl:143[inlined]
var"#draw#92"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::typeof(AlgebraOfGraphics.draw), ::AlgebraOfGraphics.Layer)#layers.jl:150
draw(::AlgebraOfGraphics.Layer)#layers.jl:150
top-level scope#Local: 7[inlined]
Commenting out # using Gadfly doesn't resolve the error, but that might be a caused by Pluto.
Pluto's live docs recognizes AoG.draw() as an AlgebraOfGraphics function, and typeof(iris_frequency) returns AlgebraOfGraphics.Layer (What you would expect.)
Does somebody have any idea how Gadfly can cause this error, and how I can solve it (apart from creating the plots in different notebooks.)

Related

Strange beahviour. `read` works when issuing commands, but not inside a function

I am just trying to restart with Julia (made some tries a couple of years ago but the libraries were still missing too much stuff).
I am now trying something really simple and can't figure out why doesn't work.
If I run these very same commands directly outside a function, I get what I want, but if I put them inside a function, I get an error when calling the read command inside my read_datafile function:
using ArgParse, ZipFile, CSV, DataFrames
function read_datafile(fp)
z = ZipFile.Reader(fp)
a = z.files[1]
df = DataFrame(CSV.File(read(a)))
return df
end
read_datafile("./folder1/test.zip")
SystemError: seek: Bad file descriptor
Stacktrace: [1] #systemerror#48 at ./error.jl:167 [inlined] [2]
systemerror at ./error.jl:167 [inlined] [3] seek at ./iostream.jl:129
[inlined] [4] read(::ZipFile.ReadableFile, ::Int64) at
/home/morgado/.julia/packages/ZipFile/fdYkP/src/ZipFile.jl:508 [5]
read at /home/morgado/.julia/packages/ZipFile/fdYkP/src/ZipFile.jl:504
[inlined] [6] read_datafile(::String) at ./In[14]:4 [7] top-level
scope at In[15]:1
EDIT:
Added more info.
using Pkg; Pkg.status()
Status `~/.julia/environments/v1.5/Project.toml`
[c7e460c6] ArgParse v1.1.1
[336ed68f] CSV v0.8.3
[a93c6f00] DataFrames v0.21.8
[92fee26a] GZip v0.5.1
[7073ff75] IJulia v1.23.1
[6f49c342] RCall v0.13.10
[fd094767] Suppressor v0.2.0
[70df011a] TableReader v0.4.0
[a5390f91] ZipFile v0.9.3
I found the answer, it's a 5 year old unsolved bug in the ZipFile package :( : https://github.com/fhs/ZipFile.jl/issues/14
Need to write the function with a global variable:
function read_datafile(fp)
global z = ZipFile.Reader(fp)
a = z.files[1]
df = DataFrame(CSV.File(read(a)))
return df
end

How do I edit Reitit routes in Reagent?

The routes created with the default reagent template look like this:
;; -------------------------
;; Routes
(def router
(reitit/router
[["/" :index]
["/items"
["" :items]
["/:item-id" :item]]
["/about" :about]]))
If I change the path of one ("/about" to "/test" below), why does it no longer work? There must be something else driving the routing, but I can't seem to figure out what.
;; -------------------------
;; Routes
(def router
(reitit/router
[["/" :index]
["/items"
["" :items]
["/:item-id" :item]]
["/test" :about]]))
This is the default reagent template (lein new reagent...) and I haven't changed anything else in the code. Any help would be greatly appreciated.
Edit - Some additional detail
I poked around in the repl a little bit in this function (from the default template):
(defn init! []
(clerk/initialize!)
(accountant/configure-navigation!
{:nav-handler
(fn [path]
(let [match (reitit/match-by-path router path)
current-page (:name (:data match))
route-params (:path-params match)]
(reagent/after-render clerk/after-render!)
(session/put! :route {:current-page (page-for current-page)
:route-params route-params})
(clerk/navigate-page! path)
))
:path-exists?
(fn [path]
(boolean (reitit/match-by-path router path)))})
(accountant/dispatch-current!)
(mount-root))
Everything looks ok to me. In fact, executing the below steps in the repl successfully navigated the browser to the correct page. I still can't enter the URL directly though.
app:problem.core=> (require '[reitit.frontend :as reitit])
nil
app:problem.core=> (reitit/match-by-path router "/test")
{:template "/test",
:data {:name :about},
:result nil,
:path-params {},
:path "/test",
:query-params {},
:parameters {:path {}, :query {}}}
app:problem.core=> (def match (reitit/match-by-path router "/test"))
#'problem.core/match
app:problem.core=> (:name (:data match))
:about
app:problem.core=> (:path-params match)
{}
app:problem.core=> (def current-page (:name (:data match)))
#'problem.core/current-page
app:problem.core=> (page-for current-page)
#'problem.core/about-page
app:problem.core=> (session/put! :route {:current-page (page-for current-page) :route-params {}})
{:route {:current-page #'problem.core/about-page, :route-params {}}}
app:problem.core=>
It looks like you changed the routes on client-side, in src/cljs/<project_name>/core.cljs, but did not change them server side in src/clj/<project_name>/handler.clj (look under the def app near the bottom of the file).
If your new to developing web applications with Clojure, I'd recommend looking at Luminus, rather than using the Reagent template. It's a much more batteries included-approach, with a lot more documentation. The book "Web Development With Clojure" is written by the same author (who is also a contributor to Reagent), and is also recommended reading.

JULIA ODBC.query MethodError: no method matching eachcolumn

I've been using Julia for some graphical results, using ODBC to conect MS Access database to get the data.
The same function worked flawlesly two weeks ago, but now it throws an error:
ERROR: MethodError: no method matching eachcolumn(::Tables.CopiedColumns{NamedTuple{(:year, :Fact),Tuple{Array{Union{Missing, Int16},1},Array{Union{Missing, Float64},1}}}})
Closest candidates are:
eachcolumn(::Union{Function, Type}, ::Tables.Schema{names,nothing}, ::Any) where names at C:\Users\myuser\.julia\packages\Tables\TA7NF\src\utils.jl:109
eachcolumn(::Union{Function, Type}, ::Tables.Schema{names,types}, ::Any) where {names, types} at C:\Users\myuser\.julia\packages\Tables\TA7NF\src\utils.jl:66
Stacktrace:
[1] #fromcolumns#410(::Bool, ::typeof(DataFrames.fromcolumns), ::Tables.CopiedColumns{NamedTuple{(:anno, :Fact),Tuple{Array{Union{Missing, Int16},1},Array{Union{Missing, Float64},1}}}}) at C:\Users\myuser\.julia\packages\DataFrames\yH0f6\src\other\tables.jl:13
[2] (::DataFrames.var"#kw##fromcolumns")(::NamedTuple{(:copycols,),Tuple{Bool}}, ::typeof(DataFrames.fromcolumns), ::Tables.CopiedColumns{NamedTuple{(:anno, :Fact),Tuple{Array{Union{Missing, Int16},1},Array{Union{Missing,
Float64},1}}}}) at .\none:0
[3] #DataFrame#412(::Bool, ::Type{DataFrame}, ::ODBC.Query{missing,NamedTuple{(:anno, :Fact),Tuple{Union{Missing, Int16},Union{Missing, Float64}}},Tuple{Array{Union{Missing, Int16},1},Array{Union{Missing, Float64},1}}}) at C:\Users\myuser\.julia\packages\DataFrames\yH0f6\src\other\tables.jl:32
[4] DataFrame(::ODBC.Query{missing,NamedTuple{(:anno, :Fact),Tuple{Union{Missing, Int16},Union{Missing, Float64}}},Tuple{Array{Union{Missing, Int16},1},Array{Union{Missing, Float64},1}}}) at C:\Users\myuser\.julia\packages\DataFrames\yH0f6\src\other\tables.jl:23
[5] #query#15(::Bool, ::Bool, ::Dict{Int64,Function}, ::typeof(ODBC.query), ::ODBC.DSN, ::String, ::Type{DataFrame}) at C:\Users\myuser\.julia\packages\ODBC\YEzHX\src\Query.jl:390
[6] query(::ODBC.DSN, ::String, ::Type{DataFrame}) at C:\Users\myuser\.julia\packages\ODBC\YEzHX\src\Query.jl:385
[7] query(::ODBC.DSN, ::String) at C:\Users\myuser\.julia\packages\ODBC\YEzHX\src\Query.jl:376
[8] top-level scope at C:\Users\myuser\Documents\Fact.jl:94
Seems like there is some kind of incompatibility between Query.jl and tables.jl
Here is the code used:
using DataFrames
using DataStreams
using ODBC
using StatsBase
using Plots
myDNS = ODBC.DSN("Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=C:/Users/myuser/Documents/Data.accdb")
strFactQuery = "SELECT YEAR(FFact) AS anno, SUM(Invoiced) AS Fact FROM Invoices GROUP BY YEAR(FFact)"
FactResults = ODBC.query(myDNS, strFactQuery)
Is there anyone with the same problem? maybe it's a Query.jl bug?
Regards
Downgrading to Tables v 0.2.11 solved the problem, but beeing able to get that version was a PITA as downgrading via pkg mannager was not possible because some dependency problems, so, all in all, I went to github, selected the version, copied the code and pasted over the library code in my environment...maybe not the ellegant way, but worked.

What's the tags meaning of Stanford dependency parser(3.9.1)?

I used the Stanford dependency parser(3.9.1) to parse a sentence, and I got the result as the following.
[[(('investigating', 'VBG'), 'nmod', ('years', 'NNS')),
(('years', 'NNS'), 'case', ('In', 'IN')),
(('years', 'NNS'), 'det', ('the', 'DT')),
(('years', 'NNS'), 'amod', ('last', 'JJ')),
(('years', 'NNS'), 'nmod', ('century', 'NN')),
(('century', 'NN'), 'case', ('of', 'IN')),
(('century', 'NN'), 'det', ('the', 'DT')),
(('century', 'NN'), 'amod', ('nineteenth', 'JJ')),
(('investigating', 'VBG'), 'nsubj', ('Planck', 'NNP')),
(('investigating', 'VBG'), 'aux', ('was', 'VBD')),
(('investigating', 'VBG'), 'dobj', ('problem', 'NN')),
(('problem', 'NN'), 'det', ('the', 'DT')),
(('problem', 'NN'), 'nmod', ('radiation', 'NN')),
(('radiation', 'NN'), 'case', ('of', 'IN')),
(('radiation', 'NN'), 'amod', ('black-body', 'JJ')),
(('radiation', 'NN'), 'acl', ('posed', 'VBN')),
(('posed', 'VBN'), 'advmod', ('first', 'RB')),
(('posed', 'VBN'), 'nmod', ('Kirchhoff', 'NNP')),
(('Kirchhoff', 'NNP'), 'case', ('by', 'IN')),
(('Kirchhoff', 'NNP'), 'advmod', ('earlier', 'RBR')),
(('earlier', 'RBR'), 'nmod:npmod', ('years', 'NNS')),
(('years', 'NNS'), 'det', ('some', 'DT')),
(('years', 'NNS'), 'amod', ('forty', 'JJ'))]]
Some of the tags meaning such as 'nmod' and 'acl' are missing in the StanfordDependencyManual.The newest manual version I can find is 3.7.0. I also find some explanation at a Standard_list_of_dependency_relations
But it still missed some tags.
Hence, my question is where can I find the newest version of the explanation of these tags? Thanks!
For the last few versions, the Stanford parser has been generating Universal Dependencies rather than Stanford Dependencies. The new relation set can be found here, and are listed below (for version 1 -- version 2 seems to be a work-in-progress still?):
acl: clausal modifier of noun
acl:relcl: relative clause modifier
advcl: adverbial clause modifier
advmod: adverbial modifier
amod: adjectival modifier
appos: appositional modifier
aux: auxiliary
auxpass: passive auxiliary
case: case marking
cc: coordination
cc:preconj: preconjunct
ccomp: clausal complement
compound: compound
compound:prt: phrasal verb particle
conj: conjunct
cop: copula
csubj: clausal subject
csubjpass: clausal passive subject
dep: dependent
det: determiner
det:predet: predeterminer
discourse: discourse element
dislocated: dislocated elements
dobj: direct object
expl: expletive
foreign: foreign words
goeswith: goes with
iobj: indirect object
list: list
mark: marker
mwe: multi-word expression
name: name
neg: negation modifier
nmod: nominal modifier
nmod:npmod: noun phrase as adverbial modifier
nmod:poss: possessive nominal modifier
nmod:tmod: temporal modifier
nsubj: nominal subject
nsubjpass: passive nominal subject
nummod: numeric modifier
parataxis: parataxis
punct: punctuation
remnant: remnant in ellipsis
reparandum: overridden disfluency
root: root
vocative: vocative
xcomp: open clausal complement
Although no longer maintained, you can get the old dependency format by setting the property depparse.language to English (see, e.g., here):
properties.setProperty("depparse.language", "English")

Using FLASM or SWFMILL to assemble/disassemble for swf files. Other options?

We have a relatively simple SWF created by a 3rd-person that basically moves around some text. I need to be able to modify that text daily, but I don't have Flash and I don't know how to use Flash. So opening and modifying it in Flash is not an option. External files are not an option either.
I tried using FLASM and SWFMILL to disassemble the SWF, but the result doesn't display the actual text.
With FLASM I used flasm -d main_ver3.swf > main_ver3.flm. This was the result: https://dl.dropboxusercontent.com/u/10067449/Flash/main_ver3.flm
With swfmill I used swfmill swf2xml main_ver3.swf main_ver3.xml. This was the result: https://dl.dropboxusercontent.com/u/10067449/Flash/main_ver3.xml
In neither of them I see some of the text that was added to the Flash, for example, "Blackberry Curve", "Apple iphone", "Nokia Lumia".
What could the problem be? The text was created using Flash's Text tool.
Thanks.
Yes, unfortunately it's not going to be as easy as replacing a text string. SWF is a complex format with a lot of possibilities. In your case the font is embedded as a set of glyphs, and the glyphs (letters) are referenced in the text objects.
The comic sans font is defined under this tag:
<DefineFont3 objectID="15" isShiftJIS="0" isUnicode="0" isANSII="0" wideGlyphOffsets="0" italic="0" bold="0" language="1" name="Comic Sans MS">
This tag has a bunch of glyphs defined in it, and you'll notice the 10th glyph (index of 9 if you start counting from 0) has a map="65" value:
<Glyph map="65">
<GlyphShape>
<edges>
<ShapeSetup x="12500" y="300" fillStyle0="1"/>
<CurveTo x1="-920" y1="0" x2="-680" y2="-2360"/>
<CurveTo x1="-260" y1="-900" x2="-390" y2="-2250"/>
...
Decimal "65" is a capital A in ASCII. So the above draw calls are drawing a capital A. Later the Text record that starts with a glyph 9 (ascii 65, capital A) and spells out 'Apple iPhone' is (I've added the letters):
<DefineText objectID="22">
<bounds>
<Rectangle left="26" right="2560" top="81" bottom="574"/>
</bounds>
<transform>
<Transform transX="0" transY="0"/>
</transform>
<records>
<TextRecord>
<records>
<TextRecord6 isSetup="1" objectID="15" y="440" fontHeight="400">
<color>
<Color red="255" green="255" blue="255"/>
</color>
</TextRecord6>
<TextRecord6 isSetup="0">
<glyphs>
<TextEntry glyph="9" advance="293"/> # 9 = A
<TextEntry glyph="25" advance="214"/> # 25 = p
<TextEntry glyph="25" advance="214"/> # 25 = p
<TextEntry glyph="21" advance="110"/> # 21 = l
<TextEntry glyph="17" advance="219"/> # 17 = e
<TextEntry glyph="0" advance="120"/> # 0 = space
<TextEntry glyph="19" advance="112"/> # 19 = i
<TextEntry glyph="25" advance="214"/> # 25 = P
<TextEntry glyph="18" advance="231"/> # 18 = h
<TextEntry glyph="24" advance="210"/> # 24 = o
<TextEntry glyph="23" advance="209"/> # 23 = n
<TextEntry glyph="17" advance="219"/> # 17 = e
</glyphs>
</TextRecord6>
<TextRecord6 isSetup="0">
<glyphs/>
</TextRecord6>
</records>
</TextRecord>
</records>
</DefineText>
I'm not sure what the advance="###" is, but I'm guessing it's defining letter spacing. The l, i and space are only about 100 units wide, while the other letters are about 200 units.
Also, SWFs are compact, so it's not guaranteed that you have every glyph necessary to replace the text at will - it might only have the glyphs needed to render the text already in the SWF.
So in short, it is possible to modify the SWF with these tools, but it'd be a bit of digging and effort for you to change this text.
Also note that you could build a SWF that decompiled with a simple replaceable textfield if the designer was careful. It would need to pick up the text for the textfield from an Array defined in AS3 code (aka actions).