Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

winston backend #18

Closed
jverzani opened this issue Sep 16, 2015 · 14 comments
Closed

winston backend #18

jverzani opened this issue Sep 16, 2015 · 14 comments

Comments

@jverzani
Copy link
Contributor

I didn't put this in a pull request, as it isn't complete, but here is a start for a Winston backend. Basic things work. A couple thoughts:

  • I used dicts for mapping Plots.jl names to Winston ones. You have functions in your backends. It seems that some of the reason for that is checking if the name passed in is correct. Shouldn't that be done before passing off to the backend (to eliminate redundant code)?
  • It seems that it might be better to dispatch on the type of plot (:linetype) rather than have all that logic in the plot! command. One benefit is that it would be easier to check if a backend supports a certain type of plot. The various types will only increase.

Anyways, for what it is worth, feel free to use this as you see fit.

immutable WinstonPackage <: PlottingPackage end

winston!() = plotter!(:winston)


# create a blank Winston.Plot object
function plot(pkg::WinstonPackage; kw...)
    @eval import DataFrames
    d = Dict(kw)

    plt = Winston.FramedPlot()

    # add the title, axis labels, and theme
    Winston.setattr(plt, "xlabel", d[:xlabel])
    Winston.setattr(plt, "ylabel", d[:ylabel])
    Winston.setattr(plt, "title",  d[:title])


    # add the legend?

    Plot(plt, pkg, 0, d, Dict[])
end

## dictionaries for conversion of Plots.jl names to Winston ones.
const winston_linestyle =  Dict(:solid=>"solid",
                                :dash=>"dash",
                                :dot=>"dotted",
                                :dashdot=>"dotdashed",
                                :dashdotdot=>"dotdashed")

const winston_marker = Dict(:none=>".",
                            :ellipse=>"circle",
                            :rect => "square",
                            :diamond=>"diamond",
                            :utriangle=>"triangle",
                            :dtriangle=>"down-triangle",
                            :cross => "cross",
                            :xcross => "cross",
                            :star1 => "asterisk",
                            :star2 => "filled circle",
                            :hexagon => "asterisk"
                            )


# plot one data series
function plot!(::WinstonPackage, plt::Plot; kw...)

    d = Dict(kw)
    e = Dict()

    # axis            # :left or :right
    # color           # can be a string ("red") or a symbol (:red) or a ColorsTypes.jl
    e[:color] = d[:color]
    #                 #   Colorant (RGB(1,0,0)) or :auto (which lets the package pick)
    # label           # string or symbol, applies to that line, may go in a legend
    # width           # width of a line
    e[:linewidth] = d[:width]
    # linetype        # :line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin, :hist, :bar

    # linestyle       # :solid, :dash, :dot, :dashdot, :dashdotdot
    e[:kind] = winston_linestyle[d[:linestyle]]
    # marker          # :none, :ellipse, :rect, :diamond, :utriangle, :dtriangle,
    #                 #   :cross, :xcross, :star1, :star2, :hexagon
    e[:symbolkind] = winston_marker[d[:marker]]

    # markercolor     # same choices as `color`, or :match will set the color to be the same as `color`


    # markersize      # size of the marker
    e[:symbolsize] = d[:markersize] / 3

    ## implement these ...
    # heatmap_c       # color cutoffs for Qwt heatmaps
    # fillto          # fillto value for area plots
    # yrightlabel     # string or symbol, label on the right (y) axis
    # size            # (Int,Int), resize the enclosing window
    # pos             # (Int,Int), move the enclosing window to this position
    # windowtitle     # string or symbol, set the title of the enclosing windowtitle
    # screen          # Integer, move enclosing window to this screen number (for multiscreen desktops)
    # show            # true or false, show the plot (in case you don't want the window to pop up right away)
    # axis
    # color
    # label
    # add to the legend
    # axis
    if d[:axis] != :left
        warn("Winston only supports one y axis")
    end


    ## do different types based on `linetype`
    ## should this use dispatch?

    ## lintype :line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin, :hist, :bar
    if d[:linetype] == :none
        Winston.add(plt.o, Winston.Points(d[:x], d[:y];
                                          [(k,v) for (k,v) in delete!(copy(e), :kind)]...))
        if d[:reg]
            ## add regression line
            xs = d[:x]
            betahat_0, betahat_1 = [ones(length(xs)) xs] \ d[:y]
            ys = betahat_0 + betahat_1 * xs
            Winston.add(plt.o, Winston.Curve(xs, ys, kind="dotted"))
        end
    elseif d[:linetype] == :line
        d[:marker] != :none && Winston.add(plt.o, Winston.Points(d[:x], d[:y];
                                                                 [(k,v) for (k,v) in delete!(copy(e), :kind)]...))
        Winston.add(plt.o, Winston.Curve(d[:x], d[:y]; [(k,v) for (k,v) in e]...))
    elseif d[:linetype] == :step
        fn = Winston.XXX

    elseif d[:linetype] == :stepinverted
        fn = Winston.XXX
    elseif d[:linetype] == :sticks
        Winston.add(plt.o, Winston.Stems(d[:x], d[:y]; [(k,v) for (k,v) in e]...))
    elseif d[:linetype] == :dots
        fn = Winston.XXX
    elseif d[:linetype] == :heatmap
        fn = Winston.XXX
    elseif d[:linetype] == :hexbin
        fn = Winston.XXX
    elseif d[:linetype] == :hist
        hst = hist(d[:y], d[:nbins])
        Winston.add(plt.o, Winston.Histogram(hst...; [(k,v) for (k,v) in delete!(copy(e), :nbins)]...))
    elseif d[:linetype] == :bar
        fn = Winston.XXX
    end


  plt
end


function savepng(::WinstonPackage, plt::PlottingObject, fn::String, args...)
  f = open(fn, "w")
  writemime(f, "image/png", plt.o)
  close(f)
end


function Base.display(::WinstonPackage, plt::Plot)
  Winston.display(plt.o)
end
@tbreloff
Copy link
Member

This is an excellent start... thanks! I mainly didn't start with dictionary mappings because

  • Dependencies aren't loaded immediately, so if you need to put a Winston.Circle (for example) in the dictionary mapping it will fail (it doesn't know about Winston yet).
  • There hasn't exactly been a 1-1 mapping for most stuff.

For this case, it seems like a dict should work fine.

You should create a pull request for this on the dev branch. The file should be in src/backends/winston.jl. If you don't care about the credit, then I'm also happy to just copy/paste. Let me know!

@jverzani
Copy link
Contributor Author

Feel free to copy and paste. That will likely be easier for you too. As for checking, I just meant to check that a proper value was passed in so that in the backend the value passed as a key is known to be correct. But you are right, there are likely values that depend on the underlying package being loaded.

@tbreloff
Copy link
Member

One of the things I'm working on now is a more complete/robust approach for
understanding what is supported with each backend, and warning the user (or
erroring if necessary). It will probably take a few iterations to get
right. Thanks for the permission to copy... I'll make a note in the
comments.

On Wed, Sep 16, 2015 at 10:44 AM, john verzani notifications@github.com
wrote:

Feel free to copy and paste. That will likely be easier for you too. As
for checking, I just meant to check that a proper value was passed in so
that in the backend the value passed as a key is known to be correct. But
you are right, there are likely values that depend on the underlying
package being loaded.


Reply to this email directly or view it on GitHub
#18 (comment).

@tbreloff
Copy link
Member

Lets leave it open... I'll close it when I'm done with Winston support.

@tbreloff tbreloff reopened this Sep 16, 2015
@tbreloff
Copy link
Member

Pretty good progress! Thanks again for the head start. Check out the Winston examples and if you're curious where I'm going with the backend code, look here

@jverzani
Copy link
Contributor Author

Nice. You are like a coding machine-- one new backend per day before lunch!
I wasn't clear exactly what fillto specifies, but Winston does have those
functions FillAbove/Below/Between functions sitting there.

On Wed, Sep 16, 2015 at 5:21 PM, Tom Breloff notifications@github.com
wrote:

Pretty good progress! Thanks again for the head start. Check out the Winston
examples
https://github.com/tbreloff/Plots.jl/blob/dev/docs/winston_examples.md
and if you're curious where I'm going with the backend code, look here
https://github.com/tbreloff/Plots.jl/blob/dev/src/backends/winston.jl


Reply to this email directly or view it on GitHub
#18 (comment).

John Verzani
Chair, Department of Mathematics
College of Staten Island, CUNY
verzani@math.csi.cuny.edu

@Evizero
Copy link
Member

Evizero commented Sep 16, 2015

+1 to coding machine

@tbreloff
Copy link
Member

Heh... Just trying to make sure the skeptics get a good first impression. I don't want people to brush it off because "you don't support XYZ so I can't use it". It's pretty easy to add features and backends now that the framework is somewhat stable.

On Sep 16, 2015, at 5:33 PM, Christof Stocker notifications@github.com wrote:

+1 to coding machine


Reply to this email directly or view it on GitHub.

@tbreloff
Copy link
Member

Also regarding fillto... in my mind it is used for 2 puposes. It can be used to turn a line plot into an area plot:
image

or could be used for bar/histogram plots as well:
image

Winston's FillAbove/Below/Between might work... maybe I need to call both FillAbove and FillBelow to make it work?

@tbreloff
Copy link
Member

Actually this was easier than expected. I used Winston.FillBetween:

plot(sin,0,3π; fillto=0.5)

tmp

x=0:0.1:3π
plot(sin,x; fillto=cumsum(randn(length(x))/10))

tmp

@tbreloff
Copy link
Member

@jverzani I'm curious... how much do you care about Winston as a backend? It's fallen a bit behind in the dev cycle, and I'm not sure I see a clear reason to use it over, say, Immerse. Would anyone be disappointed if I deprecate it at the same time I stop supporting 0.3?

@jverzani
Copy link
Contributor Author

I don't actually use it personally, but for a little side project
(GtkInteract) Winston is the only realistic backend at the moment. I'll see
if I can GtkInteract to work with the display mechanism of immerse there,
so that Plots can be supported that way. Thanks for asking.

On Sun, Oct 18, 2015 at 1:10 AM, Tom Breloff notifications@github.com
wrote:

@jverzani https://github.com/jverzani I'm curious... how much do you
care about Winston as a backend? It's fallen a bit behind in the dev cycle,
and I'm not sure I see a clear reason to use it over, say, Immerse. Would
anyone be disappointed if I deprecate it at the same time I stop supporting
0.3?


Reply to this email directly or view it on GitHub
#18 (comment).

John Verzani
Chair, Department of Mathematics
College of Staten Island, CUNY
verzani@math.csi.cuny.edu

@jverzani
Copy link
Contributor Author

Okay, adding Immerse support to my project was easy. Deprecating Winston support won't cause any concerns on my end.

@tbreloff
Copy link
Member

Ok thanks. If anyone else has an opinion on Winston, please chime in. The code in Immerse is very similar (it might have even been copied directly?) and I think it's a better backend. I want to start supporting Vega and GLPlot, and eventually Qt5, which all offer some different strengths, so the fewer distractions the better.

Also I may deprecate Qwt as well once Qt5 becomes usable.

On Oct 18, 2015, at 11:01 AM, john verzani notifications@github.com wrote:

Closed #18.


Reply to this email directly or view it on GitHub.

t-bltg pushed a commit that referenced this issue Oct 6, 2022
use version number instead of release in .travis.yml
t-bltg pushed a commit that referenced this issue Oct 6, 2022
* add debug and error stuff

* fix docstring

* Update src/pipeline.jl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants