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

Scatter plot colorbar and normalization #101

Open
Alejobep opened this issue Apr 4, 2019 · 6 comments
Open

Scatter plot colorbar and normalization #101

Alejobep opened this issue Apr 4, 2019 · 6 comments

Comments

@Alejobep
Copy link

Alejobep commented Apr 4, 2019

Hi. Thanks for developing this. This has been a life-saver. I just had a couple of questions that may or may not be related to python-ternary. I am making some scatter plots. I have a table with 3 parameters that add up to 100. I have also a 4th parameter and was planning to color the markers with a color depending on the value.

What I did not manage to see is to get the colorbar displayed (I set the boolean to True).

Also, my 4th parameter cover different orders of magnitude which means I need to log-normalize and set vmin/vmax, do you know how I could do that?

@marcharper
Copy link
Owner

Hi, take a look at #75 for an example on how to color individual points. As for the normalization, you'll need to do that before plotting.

I'm not sure why you don't see a colorbar. Can you post your code?

@Alejobep
Copy link
Author

Alejobep commented Apr 8, 2019

Hi,

Thanks for your reply.

I wused one of the examples in github and though I managed to get a colorbar, I am confused about all the kwargs I included since I just copied someone else's code without fully comprehending the meaining of each parameter and whether they were necessary or not.

Why is it necessary to declare cm=, c= and colormap=. If I remove some I miss the colorbar.

Regarding the normalization I used the logarithm because i could not figure out how to do it.

Thanks. Pasting my code below

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

cm = plt.cm.get_cmap('viridis')


dat=pd.DataFrame(columns=list('XYZV'))

dat['X']=random.sample(range(45),10)
dat['Y']=random.sample(range(45),10)
dat['Z']=100-(dat['X']+dat['Y'])
dat['V']=10**np.random.randint(0,high=10,size=10)/1e5



# sc = plt.scatter(dat.X, dat.Y, c=dat.V, vmin=0, vmax=7, s=35, cmap=cm)



scale=100



fig, tax = ternary.figure(scale=scale)
fig.set_size_inches(10, 9)

points=dat[['X','Y','Z']].values


minv=np.log10(dat.V.min())
maxv=np.log10(dat.V.max())

tax.scatter(points,s=60,vmin=minv,vmax=maxv,colormap=plt.cm.viridis,colorbar=True,c=np.log10(dat['V'].values),cmap=plt.cm.viridis)


# Decoration.
tax.boundary(linewidth=1)
tax.gridlines(multiple=10, color="gray")
tax.ticks(axis='lbr', linewidth=1, multiple=20)
tax.get_axes().axis('off')

@marcharper
Copy link
Owner

Why is it necessary to declare cm=, c= and colormap=.

It's probably just an oversight because cm is passed through to matplotlib. You need c for the colors, colormap for the spectrum, and colorbar=True to show the side colorbar, but I can probably make it so that just one of cm and colormap is required.

@Alejobep
Copy link
Author

Thanks a lot,

I have reworked my code and managed to do what I intended.
Since my coloring parameter varies in several orders of magnitude, I decided to plot the logarithm 10 of such parameter.

One reason is because it is easier to look at the colors. But another reason is that even if I manage to normalize the colormap to logarithmic scale, I am not able to have the colorbar in logarithmic scale.

I have pasted the new code. On the left side I am plotting the logarithm of the values, and on the right the values with a log-normalized colormap. In that way you see that the ternary plot are plotting the same things. Nevertheless I still do not figure out how to make the colorbar in the correct scale.


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

cm = plt.cm.get_cmap('viridis')


group=pd.DataFrame(columns=list('XYZV'))

size=4

group['X']=random.sample(range(45),size)
group['Y']=random.sample(range(45),size)
group['Z']=100-(group['X']+group['Y'])
group['V']=10**np.random.randint(0,high=5,size=size)/1e5



# sc = plt.scatter(dat.X, dat.Y, c=dat.V, vmin=0, vmax=7, s=35, cmap=cm)


name_dic={'almenningen2017':'Almenningen et al. (2017)','almenningen2016':'Almenningen et al. (2016)'}




scale=100

fig,ax=plt.subplots(ncols=2)
tax = ternary.TernaryAxesSubplot(ax=ax[0],scale=scale)
tax2 = ternary.TernaryAxesSubplot(ax=ax[1],scale=scale)
fig.set_size_inches(15, 6)
# fig2.set_size_inches(8, 6)
points=group[['X','Y','Z']].values


norm=colors.LogNorm(vmin=1e-5,vmax=1e-0)


log_c=np.log10(group['V'].values)
c=group['V'].values

cb_kwargs = {"shrink" : 0.6,
         "pad" : 0.05,
         "aspect" : 30}


tax.scatter(points,c=log_c,s=60,
            vmin=-5,vmax=0,colorbar=True,colormap='jet',cbarlabel='$log10 (Parameter)$',
            cb_kwargs=cb_kwargs,zorder=3,cmap='jet')


tax2.scatter(points,c=c,s=60,
            vmin=1e-5,vmax=1e0,colorbar=True,colormap='jet',cbarlabel='$Parameter$',
            cb_kwargs=cb_kwargs,zorder=3,cmap='jet',norm=norm)



# Axis labels. (See below for corner labels.)
fontsize = 10
offset = 0.08
tax.left_axis_label("X", fontsize=fontsize, offset=offset)
tax.right_axis_label("Y", fontsize=fontsize, offset=offset)
tax.bottom_axis_label("Z", fontsize=fontsize, offset=-offset)
tax.set_title('Example', fontsize=14)


# Decoration.
tax.boundary(linewidth=1)
tax.gridlines(multiple=10, color="gray")
tax.ticks(axis='lbr', linewidth=1, multiple=20)
tax.get_axes().axis('off')


# Axis labels. (See below for corner labels.)
tax2.left_axis_label("X", fontsize=fontsize, offset=offset)
tax2.right_axis_label("Y", fontsize=fontsize, offset=offset)
tax2.bottom_axis_label("Z", fontsize=fontsize, offset=-offset)
tax2.set_title('Example', fontsize=14)


# Decoration.
tax2.boundary(linewidth=1)
tax2.gridlines(multiple=10, color="gray")
tax2.ticks(axis='lbr', linewidth=1, multiple=20)
tax2.get_axes().axis('off')


@marcharper
Copy link
Owner

Thanks for the report. The reason is that ternary does a bit of a hack to get the colorbar on the plot and doesn't expect a norm to be passed in. However it can probably look for one in the keyword args so that option 2 works as you'd expect.

@ntropy-esa
Copy link

Thanks for this issue. It help me solve my plotting issue of a scatter with colors and a colorbar.

I now understand that we need having both:
cmap = 'jet' (for matplotlib to do its job of coloring the scatter dots)
colormap= 'jet' (for ternary's hack to place the colorbar with the right color)

I had only colormap, and was wondering why my dots where not getting the right colors!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants