Skip to content

Commit 8f51688

Browse files
committed
Merge branch 'master' of git://github.com/stevengj/PyPlot.jl
2 parents fa292d3 + 3e6e18c commit 8f51688

File tree

3 files changed

+79
-40
lines changed

3 files changed

+79
-40
lines changed

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
julia 0.2-
22
PyCall
3-
Color
3+
Color 0.3.7

src/PyPlot.jl

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ const (backend, gui) = begin
5555
# if xdpyinfo is installed.]
5656
@unix_only (@osx ? nothing : ENV["DISPLAY"])
5757

58+
# Hack to workaround matplotlib/matplotlib#2286 (PyPlot#79):
59+
# Matplotlib refuses to be interactive unless it thinks it is
60+
# running from a Python interactive prompt.
61+
let sys = pyimport("sys")
62+
if !haskey(sys, "ps1")
63+
sys["ps1"] = ">>> "
64+
end
65+
end
66+
5867
local gui::Symbol = :none
5968
if PyCall.gui == :default
6069
# try to ensure that GUI both exists and has a matplotlib backend
@@ -145,14 +154,14 @@ for (mime,fmt) in aggformats
145154
f.o["canvas"][:print_figure](io, format=$fmt, bbox_inches="tight")
146155
end
147156
if fmt != "svg"
148-
@eval mimewritable(::MIME{symbol($mime)}, f::Figure) = haskey(pycall(f.o["canvas"]["get_supported_filetypes"], PyDict), $fmt)
157+
@eval mimewritable(::MIME{symbol($mime)}, f::Figure) = !isempty(f) && haskey(pycall(f.o["canvas"]["get_supported_filetypes"], PyDict), $fmt)
149158
end
150159
end
151160

152161
# disable SVG output by default, since displaying large SVGs (large datasets)
153162
# in IJulia is slow, and browser SVG display is buggy. (Similar to IPython.)
154163
const SVG = [false]
155-
mimewritable(::MIME"image/svg+xml", f::Figure) = SVG[1] && haskey(pycall(f.o["canvas"]["get_supported_filetypes"], PyDict), "svg")
164+
mimewritable(::MIME"image/svg+xml", f::Figure) = SVG[1] && !isempty(f) && haskey(pycall(f.o["canvas"]["get_supported_filetypes"], PyDict), "svg")
156165
svg() = SVG[1]
157166
svg(b::Bool) = (SVG[1] = b)
158167

@@ -166,16 +175,15 @@ const orig_draw = pltm["draw_if_interactive"]
166175

167176
Base.isempty(f::Figure) = isempty(pycall(f["get_axes"], PyVector))
168177

178+
# monkey-patch draw_if_interactive to queue the figure for drawing in IJulia
169179
function draw_if_interactive()
170180
if isjulia_display[1]
171-
if pltm[:isinteractive]()
181+
if pycall(matplotlib["is_interactive"], Bool)
172182
manager = Gcf[:get_active]()
173183
if manager != nothing
174184
fig = Figure(manager["canvas"]["figure"])
175-
if !isempty(fig)
176-
redisplay(fig)
177-
drew_something[1] = true
178-
end
185+
redisplay(fig)
186+
drew_something[1] = true
179187
end
180188
end
181189
else
@@ -228,23 +236,39 @@ function close_queued_figs()
228236
end
229237
empty!(closequeue)
230238
drew_something[1] = false # reset until next drawing command
239+
end
240+
end
231241

232-
# if there are still open figures and the current figure is
233-
# non-empty, we want the next IJulia cell to draw into a new
234-
# figure rather than overwriting an existing one.
235-
manager = Gcf[:get_active]()
236-
if manager != nothing && !isempty(Figure(manager["canvas"]["figure"]))
237-
figure()
238-
end
242+
# hook to force new IJulia cells to create new figure objects
243+
const gcf_isnew = [false] # true to force next gcf() to be new figure
244+
force_new_fig() = gcf_isnew[1] = true
245+
246+
# monkey-patch gcf() and figure() so that we can force the creation
247+
# of new figures in new IJulia cells (e.g. after @manipulate commands
248+
# that leave the figure from the previous cell open).
249+
const orig_gcf = pltm["gcf"]
250+
const orig_figure = pltm["figure"]
251+
function figure(args...; kws...)
252+
gcf_isnew[1] = false
253+
pycall(orig_figure, PyAny, args...; kws...)
254+
end
255+
function gcf()
256+
if isjulia_display[1] && gcf_isnew[1]
257+
return figure()
258+
else
259+
return pycall(orig_gcf, PyAny)
239260
end
240261
end
241262

242263
function monkeypatch()
243264
pltm["draw_if_interactive"] = draw_if_interactive
244265
pltm["show"] = display_figs
266+
pltm["gcf"] = gcf
267+
pltm["figure"] = figure
245268
end
246269

247270
if isdefined(Main,:IJulia)
271+
Main.IJulia.push_preexecute_hook(force_new_fig)
248272
Main.IJulia.push_postexecute_hook(close_queued_figs)
249273
Main.IJulia.push_posterror_hook(close_queued_figs)
250274
end
@@ -281,7 +305,7 @@ const plt = pywrap(pltm)
281305
# export documented pyplot API (http://matplotlib.org/api/pyplot_api.html)
282306
export acorr,annotate,arrow,autoscale,autumn,axes,axhline,axhspan,axis,axvline,axvspan,bar,barbs,barh,bone,box,boxplot,broken_barh,cla,clabel,clf,clim,cohere,colorbar,colors,contour,contourf,cool,copper,csd,delaxes,disconnect,draw,errorbar,eventplot,figimage,figlegend,figtext,figure,fill_between,fill_betweenx,findobj,flag,gca,gcf,gci,get_current_fig_manager,get_figlabels,get_fignums,get_plot_commands,ginput,gray,grid,hexbin,hist2d,hlines,hold,hot,hsv,imread,imsave,imshow,ioff,ion,ishold,jet,legend,locator_params,loglog,margins,matshow,minorticks_off,minorticks_on,over,pause,pcolor,pcolormesh,pie,pink,plot,plot_date,plotfile,polar,prism,psd,quiver,quiverkey,rc,rc_context,rcdefaults,rgrids,savefig,sca,scatter,sci,semilogx,semilogy,set_cmap,setp,show,specgram,spectral,spring,spy,stackplot,stem,step,streamplot,subplot,subplot2grid,subplot_tool,subplots,subplots_adjust,summer,suptitle,switch_backend,table,text,thetagrids,tick_params,ticklabel_format,tight_layout,title,tricontour,tricontourf,tripcolor,triplot,twinx,twiny,vlines,waitforbuttonpress,winter,xkcd,xlabel,xlim,xscale,xticks,ylabel,ylim,yscale,yticks
283307

284-
for f in (:acorr,:annotate,:arrow,:autoscale,:autumn,:axes,:axhline,:axhspan,:axis,:axvline,:axvspan,:bar,:barbs,:barh,:bone,:box,:boxplot,:broken_barh,:cla,:clabel,:clf,:clim,:cohere,:colorbar,:colors,:contour,:contourf,:cool,:copper,:csd,:delaxes,:disconnect,:draw,:errorbar,:eventplot,:figimage,:figlegend,:figtext,:figure,:fill_between,:fill_betweenx,:findobj,:flag,:gca,:gcf,:gci,:get_current_fig_manager,:get_figlabels,:get_fignums,:get_plot_commands,:ginput,:gray,:grid,:hexbin,:hist2d,:hlines,:hold,:hot,:hsv,:imread,:imsave,:imshow,:ioff,:ion,:ishold,:jet,:legend,:locator_params,:loglog,:margins,:matshow,:minorticks_off,:minorticks_on,:over,:pause,:pcolor,:pcolormesh,:pie,:pink,:plot,:plot_date,:plotfile,:polar,:prism,:psd,:quiver,:quiverkey,:rc,:rc_context,:rcdefaults,:rgrids,:savefig,:sca,:scatter,:sci,:semilogx,:semilogy,:set_cmap,:setp,:specgram,:spectral,:spring,:spy,:stackplot,:stem,:streamplot,:subplot,:subplot2grid,:subplot_tool,:subplots,:subplots_adjust,:summer,:suptitle,:switch_backend,:table,:text,:thetagrids,:tick_params,:ticklabel_format,:tight_layout,:title,:tricontour,:tricontourf,:tripcolor,:triplot,:twinx,:twiny,:vlines,:waitforbuttonpress,:winter,:xkcd,:xlabel,:xlim,:xscale,:xticks,:ylabel,:ylim,:yscale,:yticks)
308+
for f in (:acorr,:annotate,:arrow,:autoscale,:autumn,:axes,:axhline,:axhspan,:axis,:axvline,:axvspan,:bar,:barbs,:barh,:bone,:box,:boxplot,:broken_barh,:cla,:clabel,:clf,:clim,:cohere,:colorbar,:colors,:contour,:contourf,:cool,:copper,:csd,:delaxes,:disconnect,:draw,:errorbar,:eventplot,:figimage,:figlegend,:figtext,:fill_between,:fill_betweenx,:findobj,:flag,:gca,:gci,:get_current_fig_manager,:get_figlabels,:get_fignums,:get_plot_commands,:ginput,:gray,:grid,:hexbin,:hist2d,:hlines,:hold,:hot,:hsv,:imread,:imsave,:imshow,:ioff,:ion,:ishold,:jet,:legend,:locator_params,:loglog,:margins,:matshow,:minorticks_off,:minorticks_on,:over,:pause,:pcolor,:pcolormesh,:pie,:pink,:plot,:plot_date,:plotfile,:polar,:prism,:psd,:quiver,:quiverkey,:rc,:rc_context,:rcdefaults,:rgrids,:savefig,:sca,:scatter,:sci,:semilogx,:semilogy,:set_cmap,:setp,:specgram,:spectral,:spring,:spy,:stackplot,:stem,:streamplot,:subplot,:subplot2grid,:subplot_tool,:subplots,:subplots_adjust,:summer,:suptitle,:switch_backend,:table,:text,:thetagrids,:tick_params,:ticklabel_format,:tight_layout,:title,:tricontour,:tricontourf,:tripcolor,:triplot,:twinx,:twiny,:vlines,:waitforbuttonpress,:winter,:xkcd,:xlabel,:xlim,:xscale,:xticks,:ylabel,:ylim,:yscale,:yticks)
285309
py_f = symbol(string("py_", f))
286310
sf = string(f)
287311
if haskey(pltm, sf)
@@ -296,6 +320,9 @@ for f in (:acorr,:annotate,:arrow,:autoscale,:autumn,:axes,:axhline,:axhspan,:ax
296320
end
297321
end
298322

323+
addhelp("figure", orig_figure)
324+
addhelp("gcf", orig_gcf)
325+
299326
# The following pyplot functions must be handled specially since they
300327
# overlap with standard Julia functions:
301328
# close, connect, fill, hist, xcorr

src/colormaps.jl

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,52 +40,64 @@ const LinearSegmentedColormap = colorsm["LinearSegmentedColormap"]
4040

4141
# most general constructors using RGB arrays of triples, defined
4242
# as for matplotlib.colors.LinearSegmentedColormap
43-
function ColorMap{T<:Real}(name::Union(String,Symbol),
44-
r::AbstractVector{(T,T,T)},
45-
g::AbstractVector{(T,T,T)},
46-
b::AbstractVector{(T,T,T)},
47-
n=max(256, length(r), length(g), length(b)),
48-
gamma=1.0)
49-
pycall(LinearSegmentedColormap, ColorMap,
50-
name, [ "red" => r, "green" => g, "blue" => b ], n, gamma)
51-
end
43+
ColorMap{T<:Real}(name::Union(String,Symbol),
44+
r::AbstractVector{(T,T,T)},
45+
g::AbstractVector{(T,T,T)},
46+
b::AbstractVector{(T,T,T)},
47+
n=max(256,length(r),length(g),length(b)), gamma=1.0) =
48+
ColorMap(name, r,g,b, Array((T,T,T),0), n, gamma)
49+
5250
# as above, but also passing an alpha array
5351
function ColorMap{T<:Real}(name::Union(String,Symbol),
5452
r::AbstractVector{(T,T,T)},
5553
g::AbstractVector{(T,T,T)},
5654
b::AbstractVector{(T,T,T)},
5755
a::AbstractVector{(T,T,T)},
58-
n=max(256, length(r), length(g), length(b)),
56+
n=max(256,length(r),length(g),length(b),length(a)),
5957
gamma=1.0)
58+
segmentdata = [ "red" => r, "green" => g, "blue" => b ]
59+
if !isempty(a)
60+
segmentdata["alpha"] = a
61+
end
6062
pycall(LinearSegmentedColormap, ColorMap,
61-
name, [ "red" => r, "green" => g, "blue" => b, "alpha" => a ],
62-
n, gamma)
63+
name, segmentdata, n, gamma)
6364
end
6465

66+
typealias AColorValue Union(ColorValue,AbstractAlphaColorValue)
6567

6668
# create from an array c, assuming linear mapping from [0,1] to c
67-
function ColorMap{T<:ColorValue}(name::Union(String,Symbol),
68-
c::AbstractVector{T},
69-
n=max(256, length(c)), gamma=1.0)
69+
function ColorMap{T<:AColorValue}(name::Union(String,Symbol),
70+
c::AbstractVector{T},
71+
n=max(256, length(c)), gamma=1.0)
7072
nc = length(c)
7173
if nc == 0
7274
throw(ArgumentError("ColorMap requires a non-empty ColorValue array"))
7375
end
7476
r = Array((Float64,Float64,Float64), nc)
75-
g = Array((Float64,Float64,Float64), nc)
76-
b = Array((Float64,Float64,Float64), nc)
77+
g = similar(r)
78+
b = similar(r)
79+
a = T <: AbstractAlphaColorValue ?
80+
similar(r) : Array((Float64,Float64,Float64), 0)
7781
for i = 1:nc
78-
rgb = convert(RGB, c[i])
7982
x = (i-1) / (nc-1)
80-
r[i] = (x, rgb.r, rgb.r)
81-
b[i] = (x, rgb.b, rgb.b)
82-
g[i] = (x, rgb.g, rgb.g)
83+
if T <: AbstractAlphaColorValue
84+
rgba = convert(AlphaColorValue{RGB{Float64},Float64}, c[i])
85+
r[i] = (x, rgba.c.r, rgba.c.r)
86+
b[i] = (x, rgba.c.b, rgba.c.b)
87+
g[i] = (x, rgba.c.g, rgba.c.g)
88+
a[i] = (x, rgba.alpha, rgba.alpha)
89+
else
90+
rgb = convert(RGB{Float64}, c[i])
91+
r[i] = (x, rgb.r, rgb.r)
92+
b[i] = (x, rgb.b, rgb.b)
93+
g[i] = (x, rgb.g, rgb.g)
94+
end
8395
end
84-
ColorMap(name, r,g,b, n, gamma)
96+
ColorMap(name, r,g,b,a, n, gamma)
8597
end
8698

87-
ColorMap{T<:ColorValue}(c::AbstractVector{T},
88-
n=max(256, length(c)), gamma=1.0) =
99+
ColorMap{T<:AColorValue}(c::AbstractVector{T},
100+
n=max(256, length(c)), gamma=1.0) =
89101
ColorMap(string("cm_", hash(c)), c, n, gamma)
90102

91103

0 commit comments

Comments
 (0)