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

pyplot can't plot heatmap properly for large size matrices #2091

Closed
Paalon opened this issue Jul 4, 2019 · 15 comments
Closed

pyplot can't plot heatmap properly for large size matrices #2091

Paalon opened this issue Jul 4, 2019 · 15 comments

Comments

@Paalon
Copy link

Paalon commented Jul 4, 2019

pyplot backend fails to plot heatmap for large size matrices.
gr backend works fine.

using Plots
pyplot()
A = rand(200, 200)
heatmap(A)

rand_200_200

A = rand(400, 400)
heatmap(A)

rand_400_400

A = rand(1000, 1000)
heatmap(A)

rand_1000_1000

The critical value is between 316 and 317.

316
rand_316_316

317
rand_317_317

316^2 = 99856 and 317^2 = 100489 so then it seems to have problems when the components are more than 100000.

julia> versioninfo()
Julia Version 1.1.1
Commit 55e36cc (2019-05-16 04:10 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin15.6.0)
  CPU: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, skylake)

(v1.1) pkg> st Plots
    Status `~/.julia/environments/v1.1/Project.toml`
  [682c06a0] JSON v0.20.0
  [91a5bcdd] Plots v0.25.2
  [2913bbd2] StatsBase v0.30.0
  [9a3f8284] Random

(v1.1) pkg> st PyPlot
    Status `~/.julia/environments/v1.1/Project.toml`
  [b964fa9f] LaTeXStrings v1.0.3
  [438e738f] PyCall v1.91.2
  [d330b81b] PyPlot v2.8.1
@asinghvi17
Copy link
Member

asinghvi17 commented Jul 12, 2019

What happens if you tile the heatmap? Something like:

using Plots
pyplot()
data = rand(Float32, 316*2, 316*2)
sc = heatmap(1:size(data, 1)÷2, 1:size(data, 2)÷2, data[1:end÷2, 1:end÷2])
heatmap!(sc, (size(data, 1)÷2 + 1):size(data, 1), 1:size(data, 2)÷2, data[(end÷2 + 1):end, 1:end÷2])
heatmap!(sc, 1:size(data, 1)÷2, (size(data, 2)÷2 + 1):size(data, 2), data[1:end÷2, (end÷2 + 1):end])
heatmap!(sc, (size(data, 1)÷2 + 1):size(data, 1), (size(data, 2)÷2 + 1):size(data, 2), data[(end÷2 + 1):end, (end÷2 + 1):end])

This is likely a backend issue, as even Makie.jl struggles with heatmaps of sufficient size (though, last I remember it was around 20,000 x 20,000, and that was an OpenGL texture issue). This approach may or may not be applicable to Pyplot.

Edited to actually plot 4 heatmaps instead of overwriting one.

@asinghvi17
Copy link
Member

This actually produces a problem on GR, where only the last heatmap is actually shown in the plot. @daschw is my Plots syntax wrong, or is this a bug in Plots/GR? There were no warnings other than "multiple series share a colorbar".

@Paalon
Copy link
Author

Paalon commented Jul 12, 2019

@asinghvi17

using Plots
pyplot()
data = rand(Float32, 316*2, 316*2)
sc = heatmap(1:size(data, 1)÷2, 1:size(data, 2)÷2, data[1:end÷2, 1:end÷2])
heatmap!(sc, (size(data, 1)÷2 + 1):size(data, 1), 1:size(data, 2)÷2, data[(end÷2 + 1):end, 1:end÷2])
heatmap!(sc, 1:size(data, 1)÷2, (size(data, 2)÷2 + 1):size(data, 2), data[1:end÷2, (end÷2 + 1):end])
heatmap!(sc, (size(data, 1)÷2 + 1):size(data, 1), (size(data, 2)÷2 + 1):size(data, 2), data[(end÷2 + 1):end, (end÷2 + 1):end])

generates

test

@asinghvi17
Copy link
Member

OK, so that's one approach to circumventing this issue for the time being...

@asinghvi17
Copy link
Member

Is it possible to "hijack" heatmap, and fragment it into multiple calls to heatmap if the dimension of the input matrix is too large? It's a bit of a hacky solution, but I think it might work.

@daschw
Copy link
Member

daschw commented Jul 12, 2019

is my Plots syntax wrong, or is this a bug in Plots/GR?

On first sight I can't see anything wrong with the syntax, so probably a Plots bug.

@daschw
Copy link
Member

daschw commented Jul 12, 2019

Is it possible to "hijack" heatmap, and fragment it into multiple calls to heatmap if the dimension of the input matrix is too large?

heatmap is not implemented as a recipe but differently for different backends in the respective bakcend code. So I think this would be rather difficult. Does GR also have the large matrix heatmap issue or is it just PyPlot?

@asinghvi17
Copy link
Member

I think GR is fine as per this issue, no?

@asinghvi17
Copy link
Member

Perhaps it's possible to special case it and recursively break up the heatmap for the Pyplot backend only?

@daschw
Copy link
Member

daschw commented Jul 13, 2019

That could be possible.

@asinghvi17
Copy link
Member

if st == :heatmap
x, y, z = heatmap_edges(x, sp[:xaxis][:scale]), heatmap_edges(y, sp[:yaxis][:scale]), transpose_z(series, z.surf)
expand_extrema!(sp[:xaxis], x)
expand_extrema!(sp[:yaxis], y)
dvals = sp[:zaxis][:discrete_values]
if !isempty(dvals)
discrete_colorbar_values = dvals
end
handle = ax."pcolormesh"(x, y, py_mask_nans(z);
label = series[:label],
zorder = series[:series_plotindex],
cmap = py_fillcolormap(series),
alpha = series[:fillalpha],
# edgecolors = (series[:linewidth] > 0 ? py_linecolor(series) : "face"),
extrakw...
)
push!(handles, handle)
end

seems to be the relevant code. Unfortunately, I'm not an expert on matplotlib, so someone else may have to take up the actual implementation.

@daschw
Copy link
Member

daschw commented Jul 13, 2019

Off-topic: How do you reference to/include code as nicely as you did in your post above, @asinghvi17 ?

@asinghvi17
Copy link
Member

asinghvi17 commented Jul 13, 2019

Go to the relevant code in the browser (on the Github interface), select the relevant linenumbers in the sidebar (they should show up in yellow), then click on the ... to the top left of the selection, and Copy permalink.
Screen Shot 2019-07-13 at 4 42 00  13900PM
@daschw

@daschw
Copy link
Member

daschw commented Jul 13, 2019

Thanks!

@tony-ko
Copy link

tony-ko commented Feb 20, 2020

Do not know, if this is still a relevant issue (at least it is open), but I don't have any trouble with plotting matrices as big as 10000x10000 in the current version (Julia v1.3.1, PyPlot v2.8.2, Plots v0.29.1)

using Plots

pyplot()

A = rand(10000, 10000)
out=heatmap(A, dpi = 1200)

savefig(out,"outheat.png")

outheat

Colorbar is a mess though.

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

5 participants