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

How to create a heatMap legend displaying the gradient scaling ? #787

Open
chmike opened this issue Feb 6, 2025 · 5 comments
Open

How to create a heatMap legend displaying the gradient scaling ? #787

chmike opened this issue Feb 6, 2025 · 5 comments

Comments

@chmike
Copy link
Contributor

chmike commented Feb 6, 2025

How do I create a heatmap legend on the right as in this matplotlib example below ? Is this possible without creating a second graphic ? Minimum coding would be preferable. Being able to adjust the hight of the color gradient bar would be also desirable.

matplotlib heatmap exampe with legend

@kortschak
Copy link
Member

This is demonstrated in the heatmap example here.

@chmike
Copy link
Contributor Author

chmike commented Feb 7, 2025

Thanks, but its not very convenient to use. For instance, it doesn't work with a 256 colors palette.
One would need to scale the thumbnail and provide multiple values to get something equivalent to the given example.
How do one scale the thumbnail ?

@chmike
Copy link
Contributor Author

chmike commented Feb 7, 2025

Also, it isn't obvious how to convert the example to generate an SVG or pdf output file.

@sbinet
Copy link
Member

sbinet commented Feb 18, 2025

here is what a modified hplot/h2d example gives:

Image

here is the simple modification:

diff --git a/hplot/h2d_example_test.go b/hplot/h2d_example_test.go
index 661acf1d..92422315 100644
--- a/hplot/h2d_example_test.go
+++ b/hplot/h2d_example_test.go
@@ -12,6 +12,7 @@ import (
 	"golang.org/x/exp/rand"
 	"gonum.org/v1/gonum/mat"
 	"gonum.org/v1/gonum/stat/distmv"
+	"gonum.org/v1/plot/palette"
 	"gonum.org/v1/plot/plotter"
 	"gonum.org/v1/plot/vg"
 )
@@ -72,7 +73,8 @@ func ExampleH2D_withLegend() {
 		v = dist.Rand(v)
 		h2d.Fill(v[0], v[1], 1)
 	}
-	h := hplot.NewH2D(h2d, nil)
+	pal := palette.Rainbow(50, palette.Yellow, palette.Green, 1, 0.5, 0.5)
+	h := hplot.NewH2D(h2d, pal)
 
 	p := hplot.New()
 	p.Title.Text = "Hist-2D"
 }

ie:

func ExampleH2D_withLegend() {
	h2d := hbook.NewH2D(100, -10, 10, 100, -10, 10)

	const npoints = 10000

	dist, ok := distmv.NewNormal(
		[]float64{0, 1},
		mat.NewSymDense(2, []float64{4, 0, 0, 2}),
		rand.New(rand.NewSource(1234)),
	)
	if !ok {
		log.Fatalf("error creating distmv.Normal")
	}

	v := make([]float64, 2)
	// Draw some random values from the standard
	// normal distribution.
	for i := 0; i < npoints; i++ {
		v = dist.Rand(v)
		h2d.Fill(v[0], v[1], 1)
	}
	pal := palette.Rainbow(50, palette.Yellow, palette.Green, 1, 0.5, 0.5)
	h := hplot.NewH2D(h2d, pal)

	p := hplot.New()
	p.Title.Text = "Hist-2D"
	p.X.Label.Text = "x"
	p.Y.Label.Text = "y"

	p.Add(h)
	p.Add(plotter.NewGrid())

	fig := hplot.Figure(p, hplot.WithLegend(h.Legend()))
	err := hplot.Save(fig, 20*vg.Centimeter, 20*vg.Centimeter, "testdata/h2d_plot_legend.png")
	if err != nil {
		log.Fatal(err)
	}
}

modifiying for a SVG is relatively trivial:

diff --git a/hplot/h2d_example_test.go b/hplot/h2d_example_test.go
index 661acf1d..b13aa8e5 100644
--- a/hplot/h2d_example_test.go
+++ b/hplot/h2d_example_test.go
@@ -12,6 +12,7 @@ import (
 	"golang.org/x/exp/rand"
 	"gonum.org/v1/gonum/mat"
 	"gonum.org/v1/gonum/stat/distmv"
+	"gonum.org/v1/plot/palette"
 	"gonum.org/v1/plot/plotter"
 	"gonum.org/v1/plot/vg"
 )
@@ -72,7 +73,8 @@ func ExampleH2D_withLegend() {
 		v = dist.Rand(v)
 		h2d.Fill(v[0], v[1], 1)
 	}
-	h := hplot.NewH2D(h2d, nil)
+	pal := palette.Rainbow(50, palette.Yellow, palette.Green, 1, 0.5, 0.5)
+	h := hplot.NewH2D(h2d, pal)
 
 	p := hplot.New()
 	p.Title.Text = "Hist-2D"
@@ -83,8 +85,12 @@ func ExampleH2D_withLegend() {
 	p.Add(plotter.NewGrid())
 
 	fig := hplot.Figure(p, hplot.WithLegend(h.Legend()))
-	err := hplot.Save(fig, 10*vg.Centimeter, 10*vg.Centimeter, "testdata/h2d_plot_legend.png")
+	err := hplot.Save(fig, 20*vg.Centimeter, 20*vg.Centimeter, "testdata/h2d_plot_legend.svg")
 	if err != nil {
 		log.Fatal(err)
 	}
 }

@sbinet
Copy link
Member

sbinet commented Feb 18, 2025

a smarter plotter.PaletteThumbnailers (or different) could compute the available vertical headroom, adapt each ladder dimension and take the whole space.

(here, I cheated and chose 50 as the number of different colors so the legend would take the whole vertical space)

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