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

Blank Heatmap #197

Open
sdebesai opened this issue Aug 11, 2022 · 6 comments
Open

Blank Heatmap #197

sdebesai opened this issue Aug 11, 2022 · 6 comments

Comments

@sdebesai
Copy link

Hi,

First I wanted to say thank you for creating such a well documented and useful package. I am attempting to use the heatmap() function but my current output is just a blank plot and I'm having trouble understanding why. I tried creating a dictionary where I mapped points to random values instead of the actual data I'm attempting to plot to see if it was an issue with my data but that's not working either. I think I'm likely doing something silly (maybe in my data generation?) but am pretty stuck and would appreciate any insight. As a note I'm omitting the boundaries where a coordinate is 0 because the distribution I hope to eventually plot behaves weirdly there, but this is something I intend to address later. Here's the code snippet:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import ternary
import random

def gen_rand_data(f1_list_all=np.linspace(0,1,100)):
data = {}
for f1 in f1_list_all:
if f1 != 0:
f2_list=f1_list_all[np.where(f1_list_all< 1-f1)]
f1_list=f1*np.ones(f2_list.shape[0])

        for f2 in f2_list:
            if f2 > 0:
                val=random.uniform(0, 1)
                data[(f1, f2)] = val
                color=ternary.colormapping.colormapper(val) #testing to see that function converts to colors.
                print(color)
#print(data)
return data

def main():
f1_list_all=np.linspace(0,1,100)
#data, Z=gen_data(f1_list_all)
data = gen_rand_data(f1_list_all=np.linspace(0,1,100))

scale = 1

fig, ax = plt.subplots()
ax.axis("off")
figure, tax = ternary.figure(ax=ax, scale=scale)

tax.heatmap(data, cmap=None)

axes_colors = {'b': 'g', 'l': 'r', 'r': 'b'}
tax.boundary(linewidth=2.0)

tax.left_axis_label("$f_1$", offset=0.16)
tax.right_axis_label("$f_2$", offset=0.16)
tax.bottom_axis_label("$f_3$", offset=0.06)

tax.gridlines(multiple=1, linewidth=2,
          horizontal_kwargs={'color': axes_colors['b']},
          left_kwargs={'color': axes_colors['l']},
          right_kwargs={'color': axes_colors['r']},
          alpha=0.7)

# Set and format axes ticks.
ticks = [i / float(scale) for i in range(scale+1)]
tax.ticks(ticks=ticks, axis='rlb', linewidth=1, clockwise=True,
      axes_colors=axes_colors, offset=0.03, tick_formats="%0.1f")

tax.clear_matplotlib_ticks()
tax._redraw_labels()
plt.tight_layout()
tax.show()
figure.savefig('simplex_plot.png')

Thank you!

@sdebesai
Copy link
Author

sdebesai commented Aug 12, 2022

Hi,

I realize the formatting of the code got messed up so I'm attaching a screenshot. Thanks in advance!

Screen Shot 2022-08-12 at 11 28 23 AM

Screen Shot 2022-08-12 at 11 28 36 AM

@bmondal94
Copy link

  1. You want to draw the heatmap with scale=1. Please check out discussion Heatmap scale greater than 1 vs less than equal to 1 #191.
  2. add style='h' in tax.heatmap.
  3. Note: In tax.gridlines when scale=1, multiple=1 will give you only the border lines. I am guessing you wanted multiple=0.1.
  4. Note: If scale = 1 ticks = [i / float(scale) for i in range(scale+1)] will give you only two ticks: 0 and 1.

@bmondal94
Copy link

"As a note I'm omitting the boundaries where a coordinate is 0 because the distribution I hope to eventually plot behaves weirdly there,"

Don't worry. python-ternary takes care of that (for style="h"). You can add the 0 to your data list.

@disouzam
Copy link

disouzam commented Jan 1, 2024

Hello, @sdebesai :

Were you able to work around your issue? I'm interested in using this library/package and I am stuck as you were.

And, @bmondal94 , I tried to follow your advice in this discussion and even then I was not able to get pass the issues found by @sdebesai. I'm assuming I'm missing some key concept or key configuration but I am not sure what.

This is the plot I was able to get using the script by @sdebesai and your advices:

simplex_plot

@bmondal94
Copy link

Dear @disouzam ,

  1. To draw the heatmap with scale=1 refer to the suggestions in the issue Heatmap scale greater than 1 vs less than equal to 1 #191 .
  2. The rest of the comments above are in response to the problem: "... but my current output is just a blank plot ...".
  3. Here is a working example following the suggestion from Heatmap scale greater than 1 vs less than equal to 1 #191.
#Here I am following suggestion 2 from issue #191: Re-scale the data to 100-scale -> plot -> Adjust ticks to scale 1.
#This assumes I have no control on the initial data. I am only allowed to post-process the initial data before plotting.

import numpy as np
import matplotlib.pyplot as plt
import ternary
import random


#==============================================
def gen_rand_data(scale=1, npoints=100):
    data = {}
    f1_list_all=np.linspace(0,scale,npoints+1)
    for f1 in f1_list_all:
        f2_list=f1_list_all[np.where(f1_list_all<= scale-f1)]
        for f2 in f2_list:
            val=random.uniform(0, 1)
            data[(f1, f2)] = val
    return data

#==============================================
scale = 1
rescale = scale if scale > 1 else 100

data = gen_rand_data(scale=scale) # This assume no control over the initial data. For e.g. the data was downloaded from some data source where I have no control.
rescaled_data = {(key[0]*rescale, key[1]*rescale): val for key, val in data.items()}
# data = gen_rand_data(scale=rescale) # This assumes you generate your own data. 
# rescaled_data = data.copy()

#==============================================
fig, ax = plt.subplots()
ax.axis("off")
figure, tax = ternary.figure(ax=ax, scale=rescale)

tax.heatmap(rescaled_data,  style="h", cmap=None)

axes_colors = {'b': 'g', 'l': 'r', 'r': 'b'}
tax.boundary(linewidth=2.0)

tax.left_axis_label("$f_1$", offset=0.16)
tax.right_axis_label("$f_2$", offset=0.16)
tax.bottom_axis_label("$f_3$", offset=0.06)

# Note: re-scaled data coordinates are in scale 100. 
# Adjust the tick labels in the original scale 1.
number_of_ticks = 10
ticks = list(np.linspace(0,scale,number_of_ticks+1))
tax.ticks(ticks=ticks, multiple=number_of_ticks,axis='rlb', linewidth=1, clockwise=True,
  axes_colors=axes_colors, offset=0.03, tick_formats="%0.1f")

# tax.gridlines(multiple=number_of_ticks, linewidth=2,
#       horizontal_kwargs={'color': axes_colors['b']},
#       left_kwargs={'color': axes_colors['l']},
#       right_kwargs={'color': axes_colors['r']},
#       alpha=0.7)

tax.clear_matplotlib_ticks()
tax._redraw_labels()
plt.tight_layout()
tax.show()

@disouzam
Copy link

disouzam commented Jan 2, 2024

Dear @disouzam ,

  1. To draw the heatmap with scale=1 refer to the suggestions in the issue Heatmap scale greater than 1 vs less than equal to 1 #191 .
  2. The rest of the comments above are in response to the problem: "... but my current output is just a blank plot ...".
  3. Here is a working example following the suggestion from Heatmap scale greater than 1 vs less than equal to 1 #191.
#Here I am following suggestion 2 from issue #191: Re-scale the data to 100-scale -> plot -> Adjust ticks to scale 1.
#This assumes I have no control on the initial data. I am only allowed to post-process the initial data before plotting.

import numpy as np
import matplotlib.pyplot as plt
import ternary
import random


#==============================================
def gen_rand_data(scale=1, npoints=100):
    data = {}
    f1_list_all=np.linspace(0,scale,npoints+1)
    for f1 in f1_list_all:
        f2_list=f1_list_all[np.where(f1_list_all<= scale-f1)]
        for f2 in f2_list:
            val=random.uniform(0, 1)
            data[(f1, f2)] = val
    return data

#==============================================
scale = 1
rescale = scale if scale > 1 else 100

data = gen_rand_data(scale=scale) # This assume no control over the initial data. For e.g. the data was downloaded from some data source where I have no control.
rescaled_data = {(key[0]*rescale, key[1]*rescale): val for key, val in data.items()}
# data = gen_rand_data(scale=rescale) # This assumes you generate your own data. 
# rescaled_data = data.copy()

#==============================================
fig, ax = plt.subplots()
ax.axis("off")
figure, tax = ternary.figure(ax=ax, scale=rescale)

tax.heatmap(rescaled_data,  style="h", cmap=None)

axes_colors = {'b': 'g', 'l': 'r', 'r': 'b'}
tax.boundary(linewidth=2.0)

tax.left_axis_label("$f_1$", offset=0.16)
tax.right_axis_label("$f_2$", offset=0.16)
tax.bottom_axis_label("$f_3$", offset=0.06)

# Note: re-scaled data coordinates are in scale 100. 
# Adjust the tick labels in the original scale 1.
number_of_ticks = 10
ticks = list(np.linspace(0,scale,number_of_ticks+1))
tax.ticks(ticks=ticks, multiple=number_of_ticks,axis='rlb', linewidth=1, clockwise=True,
  axes_colors=axes_colors, offset=0.03, tick_formats="%0.1f")

# tax.gridlines(multiple=number_of_ticks, linewidth=2,
#       horizontal_kwargs={'color': axes_colors['b']},
#       left_kwargs={'color': axes_colors['l']},
#       right_kwargs={'color': axes_colors['r']},
#       alpha=0.7)

tax.clear_matplotlib_ticks()
tax._redraw_labels()
plt.tight_layout()
tax.show()

Thanks a lot, @bmondal94 , for your quick and kind reply!

Your corrected script now works perfectly here as seen in the picture below. Now my task will be to transfer this knowledge to my real case example (plot a CaO-MgO-SiO2-Al2O3 phase diagram, with MgO fixed at 10% and poles representing CaO, SiO2 and Al2O3). I've tried earlier with no success. I will tune the script you provided to me as a baseline.

simplex_plot

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