only one colorbar per subplot in pyplot

This commit is contained in:
Daniel Schwabeneder 2017-09-09 11:21:39 +02:00
parent 7dfa1ec984
commit 518fba759f
2 changed files with 48 additions and 64 deletions

View File

@ -444,11 +444,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
xyargs = (st in _3dTypes ? (x,y,z) : (x,y)) xyargs = (st in _3dTypes ? (x,y,z) : (x,y))
# handle zcolor and get c/cmap # handle zcolor and get c/cmap
extrakw = KW() needs_colorbar = hascolorbar(sp)
extrakw = if needs_colorbar
vmin, vmax = get_clims(sp)
KW(:vmin => vmin, :vmax => vmax)
else
KW()
end
# holds references to any python object representing the matplotlib series # holds references to any python object representing the matplotlib series
handles = [] handles = []
needs_colorbar = false
discrete_colorbar_values = nothing discrete_colorbar_values = nothing
@ -495,11 +500,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:linewidth => py_dpi_scale(plt, series[:linewidth]), :linewidth => py_dpi_scale(plt, series[:linewidth]),
:linestyle => py_linestyle(st, series[:linestyle]) :linestyle => py_linestyle(st, series[:linestyle])
) )
clims = sp[:clims] if needs_colorbar
if is_2tuple(clims)
extrakw = KW()
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
kw[:norm] = pycolors["Normalize"](; extrakw...) kw[:norm] = pycolors["Normalize"](; extrakw...)
end end
lz = collect(series[:line_z]) lz = collect(series[:line_z])
@ -563,18 +564,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
if series[:markershape] != :none && st in (:path, :scatter, :path3d, if series[:markershape] != :none && st in (:path, :scatter, :path3d,
:scatter3d, :steppre, :steppost, :scatter3d, :steppre, :steppost,
:bar) :bar)
extrakw = KW()
if series[:marker_z] == nothing if series[:marker_z] == nothing
extrakw[:c] = py_color_fix(py_markercolor(series), x) extrakw[:c] = py_color_fix(py_markercolor(series), x)
else else
extrakw[:c] = convert(Vector{Float64}, series[:marker_z]) extrakw[:c] = convert(Vector{Float64}, series[:marker_z])
extrakw[:cmap] = py_markercolormap(series) extrakw[:cmap] = py_markercolormap(series)
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
end
needs_colorbar = true
end end
xyargs = if st == :bar && !isvertical(series) xyargs = if st == :bar && !isvertical(series)
(y, x) (y, x)
@ -624,11 +618,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end end
if st == :hexbin if st == :hexbin
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
end
handle = ax[:hexbin](x, y; handle = ax[:hexbin](x, y;
label = series[:label], label = series[:label],
zorder = series[:series_plotindex], zorder = series[:series_plotindex],
@ -646,12 +635,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
z = transpose_z(series, z.surf) z = transpose_z(series, z.surf)
needs_colorbar = true needs_colorbar = true
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
end
if st == :contour3d if st == :contour3d
extrakw[:extend3d] = true extrakw[:extend3d] = true
end end
@ -688,11 +671,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end end
z = transpose_z(series, z) z = transpose_z(series, z)
if st == :surface if st == :surface
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
end
if series[:fill_z] != nothing if series[:fill_z] != nothing
# the surface colors are different than z-value # the surface colors are different than z-value
extrakw[:facecolors] = py_shading(series[:fillcolor], transpose_z(series, series[:fill_z].surf)) extrakw[:facecolors] = py_shading(series[:fillcolor], transpose_z(series, series[:fill_z].surf))
@ -727,10 +705,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end end
end end
# no colorbar if we are creating a surface LightSource
if haskey(extrakw, :facecolors)
needs_colorbar = false
end
elseif typeof(z) <: AbstractVector elseif typeof(z) <: AbstractVector
# tri-surface plot (http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#tri-surface-plots) # tri-surface plot (http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#tri-surface-plots)
@ -788,11 +762,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
discrete_colorbar_values = dvals discrete_colorbar_values = dvals
end end
clims = sp[:clims]
zmin, zmax = ignorenan_extrema(z)
extrakw[:vmin] = (is_2tuple(clims) && isfinite(clims[1])) ? clims[1] : zmin
extrakw[:vmax] = (is_2tuple(clims) && isfinite(clims[2])) ? clims[2] : zmax
handle = ax[:pcolormesh](x, y, py_mask_nans(z); handle = ax[:pcolormesh](x, y, py_mask_nans(z);
label = series[:label], label = series[:label],
zorder = series[:series_plotindex], zorder = series[:series_plotindex],
@ -844,30 +813,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
# # smoothing # # smoothing
# handleSmooth(plt, ax, series, series[:smooth]) # handleSmooth(plt, ax, series, series[:smooth])
# add the colorbar legend
if needs_colorbar && sp[:colorbar] != :none
# add keyword args for a discrete colorbar
handle = handles[end]
kw = KW()
if discrete_colorbar_values != nothing
locator, formatter = get_locator_and_formatter(discrete_colorbar_values)
# kw[:values] = 1:length(discrete_colorbar_values)
kw[:values] = sp[:zaxis][:continuous_values]
kw[:ticks] = locator
kw[:format] = formatter
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
end
# create and store the colorbar object (handle) and the axis that it is drawn on.
# note: the colorbar axis is positioned independently from the subplot axis
fig = plt.o
cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym()))
cb = fig[:colorbar](handle; cax = cbax, kw...)
cb[:set_label](sp[:colorbar_title])
sp.attr[:cbar_handle] = cb
sp.attr[:cbar_ax] = cbax
end
# handle area filling # handle area filling
fillrange = series[:fillrange] fillrange = series[:fillrange]
if fillrange != nothing && st != :contour if fillrange != nothing && st != :contour
@ -1042,6 +987,32 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# ax[:set_title](sp[:title], loc = loc) # ax[:set_title](sp[:title], loc = loc)
end end
# add the colorbar legend
if hascolorbar(sp)
# add keyword args for a discrete colorbar
slist = series_list(sp)
colorbar_series = slist[findfirst(hascolorbar.(slist))]
handle = colorbar_series[:serieshandle][end]
kw = KW()
if !isempty(sp[:zaxis][:discrete_values]) && colorbar_series[:seriestype] == :heatmap
locator, formatter = get_locator_and_formatter(sp[:zaxis][:discrete_values])
# kw[:values] = 1:length(sp[:zaxis][:discrete_values])
kw[:values] = sp[:zaxis][:continuous_values]
kw[:ticks] = locator
kw[:format] = formatter
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
end
# create and store the colorbar object (handle) and the axis that it is drawn on.
# note: the colorbar axis is positioned independently from the subplot axis
fig = plt.o
cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym()))
cb = fig[:colorbar](handle; cax = cbax, kw...)
cb[:set_label](sp[:colorbar_title])
sp.attr[:cbar_handle] = cb
sp.attr[:cbar_ax] = cbax
end
# framestyle # framestyle
if !ispolar(sp) && !is3d(sp) if !ispolar(sp) && !is3d(sp)
if sp[:framestyle] == :semi if sp[:framestyle] == :semi

View File

@ -561,12 +561,25 @@ end
_update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) _update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax)
function hascolorbar(series::Series)
st = series[:seriestype]
hascbar = st in (:heatmap, :contour)
if series[:marker_z] != nothing || series[:line_z] != nothing
hascbar = true
end
# no colorbar if we are creating a surface LightSource
if xor(st == :surface, series[:fill_z] != nothing)
hascbar = true
end
return hascbar
end
function hascolorbar(sp::Subplot) function hascolorbar(sp::Subplot)
cbar = sp[:colorbar] cbar = sp[:colorbar]
hascbar = false hascbar = false
if cbar != :none if cbar != :none
for series in series_list(sp) for series in series_list(sp)
if series[:seriestype] in (:heatmap, :contour, :surface) || series[:marker_z] != nothing || series[:line_z] != nothing if hascolorbar(series)
hascbar = true hascbar = true
end end
end end