# Logarithmic normalization for colorscale/colorbar?

Is there a proper way to display log-normal values with a colorscale and colobar with Scatter3d? The options found at https://plotly.com/python/colorscales/ are not sufficient because they do not show the lower valuesâ€”which are the ones of interest. Is there some way to do a log normalization like in matplotlib?

In the example below, consider `val` which has a log normal distribution and is indexed by `x, y, z` which are linear. Notice how in plotly the data are mostly blue and in matplotlib the whole colormap is used.

``````import plotly
import plotly.graph_objs as go

x = np.random.uniform(1, 100, 100)
y = np.random.uniform(1, 100, 100)
z = np.random.uniform(1, 100, 100)
val = np.random.lognormal(8, 1, 100)

trace1 = go.Scatter3d(x=x,
y=y,
z=z,
mode='markers',
marker=dict(
color=val,
showscale=True,
size=8,
colorscale='rdylbu_r',
#colorscale=[[0, 'rgb(250, 250, 250)'],        #0   # from plotly docs
#[1./10000, 'rgb(200, 200, 200)'],  #10
#[1./1000, 'rgb(150, 150, 150)'],   #100
#[1./100, 'rgb(100, 100, 100)'],    #1000
#[1./10, 'rgb(50, 50, 50)'],        #10000
#[1., 'rgb(0, 0, 0)'],       ],     #100000
colorbar=dict(x=0.8),
))

layout = go.Layout(scene=dict(xaxis=dict(title='x'),
yaxis=dict(title='y'),
zaxis=dict(title='z'),
))

data = [trace1]

fig = go.Figure(data=data, layout=layout)

plotly.offline.plot(fig, filename='log-test.html')
``````
``````import matplotlib as mpl
import matplotlib.pyplot as plt

fig = plt.figure(dpi=125)
ax = fig.gca(projection='3d')

cax = ax.scatter(x, y, z, c=val,
cmap=plt.cm.RdYlBu_r,
norm=mpl.colors.LogNorm(vmin=val.min(), vmax=val.max())
)
fig.colorbar(cax)
plt.show()
``````

My apologies, I found the answer (below) however, it may be nice to have a colorscale type = log feature.

``````import plotly
import plotly.graph_objs as go

x = np.random.uniform(1, 100, 100)
y = np.random.uniform(1, 100, 100)
z = np.random.uniform(1, 100, 100)
val = np.random.lognormal(8, 1, 100)

tickvals = [1e2, 2e2, 3e2, 4e2, 5e2, 6e2, 7e2, 8e2, 9e2, 1e2,
1e3, 2e3, 3e3, 4e3, 5e3, 6e3, 7e3, 8e3, 9e3, 1e4,
2e4, 3e4, 4e4]

trace1 = go.Scatter3d(x=x,
y=y,
z=z,
mode='markers',
marker=dict(
color=np.log10(val),
showscale=True,
size=8,
colorscale='rdylbu_r',
colorbar=dict(
x=0.8,
tickvals=np.log10(tickvals),
ticktext=tickvals,
),
))

layout = go.Layout(scene=dict(xaxis=dict(title='x'),
yaxis=dict(title='y'),
zaxis=dict(title='z'),
))

data = [trace1]

fig = go.Figure(data=data, layout=layout)

plotly.offline.plot(fig, filename='log-test.html')

``````
1 Like

I will bump this up because this would be a very useful feature!

2 Likes

Hi. Was this colorscale type implemented? We noticed that the description for the dtick property hints that this might be implemented but I am not getting it to work on the codepen.

This is a description of dtick on layout.coloraxis.colorbar

" If the axis `type` is â€ślogâ€ť, then ticks are set every 10^(n"dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, â€¦ set dtick to 1. To set tick marks at 1, 100, 10000, â€¦ set dtick to 2"

``````var layout = {
coloraxis: {
autocolorscale: false,
colorscale: 'Rainbow',
showscale: true,
type: 'log',
colorbar: {
xref:'container',
tick0:0.1,
dtick:2
}
},
``````
1 Like