HoloViews create interpolated colorful heatmap - python

I have created a heatmap using holoviews on top of bokeh
import numpy as np
import pandas as pd
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')
df = pd.DataFrame(np.random.rand(10, 10) * 100)
heatmap = hv.HeatMap((df.columns, df.index, df))
heatmap.opts(width=500, title='Thermal map', colorbar=True, tools=['hover'], cmap='Turbo')
and got the following heatmap:
How can I make the heatmap color interpolate same as the colorbar
Like moving from pixel to pixel as a gradient
similar to:
Thanks!!

Relying on post comments I was able to interpolate heatmap, especially James A. Bednar comment.
import holoviews as hv
from holoviews import opts
from holoviews.operation.datashader import regrid
df = pd.DataFrame(np.random.rand(10, 10) * 100)
img = hv.Image((df.columns, df.index, df))
img.opts(width=500, height=500, title='Thermal map', cmap='RdYlBu_r' ,tools['hover'], colorbar=True)
inter_img = regrid(img, upsample=True, interpolation='bilinear')
img + inter_img
Thanks so much

Related

Plot a best fit over a scatter plot with holoviews

I am trying to make a best fit line for all of my graphs in holoviews, right now it just makes a line based on all the data instead of each graph individually.
vdims = [('year avg', 'Yearly Average Temperature')]
ds = hv.Dataset(temp, ['Year','State Name'], vdims)
ds = ds.aggregate(function=np.mean)
scat = hv.Scatter(ds,'Year','year avg')
layout = ds.to(hv.Scatter,'Year','year avg') * hv.Slope.from_scatter(scat)
layout.opts(opts.Curve(width=800, height=400, framewise=True))
Which gives this
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import holoviews as hv
hv.extension('bokeh')
from holoviews import opts
from holoviews.plotting.links import DataLink
import hvplot.pandas
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
df['Even'] = df['D']%2 == 0
vdims = [('A', 'A')]
ds = hv.Dataset(df, ['B','Even'], vdims)
#ds = ds.aggregate(function=np.mean) this does nothing here, in my code it takes the mean of 100 or so data points in each group for each year.
scat = hv.Scatter(ds,'B','A')
layout = ds.to(hv.Scatter,'B','A') * hv.Slope.from_scatter(scat)
layout.opts(opts.Curve(width=800, height=400, framewise=True))
The idea is to make a scatter plot grouped by a variable in the dataframe, in this case if D is even or odd, and also plot a best fit line of that same grouped scatter plot.
What I have is a set of grouped scatter plots but with a best fit line based on all of the data combined, not grouped by even and odd.

Plotly: How to plot histogram in Root style showing only the contours of the histogram?

I want to make a histogram with this style:
But using plotly in Python. I.e. I want to merge the bars and plot only the contour. I am using this code:
import plotly.graph_objects as go
import numpy as np
x = np.random.randn(500)
fig = go.Figure(data=[go.Histogram(x=x)])
fig.show()
I have been looking for examples on how to do this but could not find any.
Your best option is to handle the histogram with numpy like count, index = np.histogram(df['data'], bins=25) , and then use go.Scatter() and set the linetype to horizontal, vertical, horizontal with line=dict(width = 1, shape='hvh'). Take a look at the very last section why go.Histogram() will not be your best option. With a few other specifications for the layout of go.Scatter(), the snippet below will produce the following plot:
Complete code
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px
pio.templates.default = "plotly_white"
# random numbers to a df
np.random.seed(12)
df = pd.DataFrame({'data': np.random.randn(500)})
# produce histogram data wiht numpy
count, index = np.histogram(df['data'], bins=25)
# plotly, go.Scatter with line shape set to 'hvh'
fig = go.Figure()
fig.add_traces(go.Scatter(x=index, y = count,
line=dict(width = 1, shape='hvh')))
# y-axis cosmetics
fig.update_yaxes(
showgrid=False,
ticks="inside",
tickson="boundaries",
ticklen=10,
showline=True,
linewidth=1,
linecolor='black',
mirror=True,
zeroline=False)
# x-axis cosmetics
fig.update_xaxes(
showgrid=False,
ticks="inside",
tickson="boundaries",
ticklen=10,
showline=True,
linewidth=1,
linecolor='black',
mirror=True,
zeroline=False)
fig.show()
Why go.Scatter() and not go.Histogram()?
The closest you'll get to your desired plot using your approach with fig = go.Figure(data=[go.Histogram(x=x)]) is this:
And that's pretty close, but you specifically wanted to exclude the vertical lines for each "bar". And I have yet not found a way to exclude or hide them with the go.Histogram setup.
Code for go.Histogram()
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px
pio.templates.default = "plotly_white"
import numpy as np
x = np.random.randn(500)
fig = go.Figure(data=[go.Histogram(x=x)])
fig.update_traces(marker=dict(color='rgba(0,0,0,0)', line=dict(width=1, color='blue')))
fig.show()
for a variation plotly.go.Histogram(): Show only horizontal lines of distribution. Plot just the lines
using pandas instead of numpy to build data for histogram then plotting as a line scatter
import plotly.graph_objects as go
import numpy as np
import pandas as pd
x = np.random.randn(100)
# build data frame that is histogram
df = pd.cut(x, bins=10).value_counts().to_frame().assign(
l=lambda d: pd.IntervalIndex(d.index).left,
r=lambda d: pd.IntervalIndex(d.index).right,
).sort_values(["l","r"]).rename(columns={0:"y"}).astype(float)
# lines in plotly are delimited by none
def line_array(df, cols):
return np.pad(
df.loc[:, cols].values, [(0, 0), (0, 1)], constant_values=None
).reshape(1, (len(df) * 3))[0]
# plot just lines
go.Figure(go.Scatter(x=line_array(df, ["l","r"]), y=line_array(df, ["y","y"]), marker={"color":"black"}))

How to make animated 3D scatter plot in plotly

My goal is to create an animation with my 3D data in plotly.
I have 3 variables x,y,z for simplicity and I plot the 4th value depending on these x,y,z.
I create a 3D scatter plot where the 4th dim sort to speak is the color like this:
from numpy import genfromtxt
import numpy as np
import plotly.io as pio
import plotly.express as px
pio.renderers.default = 'notebook'
import plotly.graph_objects as go
import math
import pandas as pd
data = pd.read_csv("paramtp_1e-05_big.txt")
data.head()
data = data.iloc[::10, :]
color_data = data['gopt'].astype(float).round(decimals=2)
color_data[color_data>= 10] = 10
color_data_nopt = data['nopt'].astype(float).round(decimals=3)
color_data_mc = data['mc'].astype(float).round(decimals=3)
color_data_P= data['P']
color_data_P[color_data_P >= 1] = 1
data= data.replace(np.nan, '', regex=True)
data.tail()
fig = px.scatter_3d(data, x='NpN0', y='s', z='mu',log_x=True, log_z=True,
opacity = 0.5,
color=color_data,color_continuous_scale=px.colors.sequential.Viridis)
fig.add_trace(
go.Scatter(
mode='markers',
marker=dict(
size=1,
opacity=0.5,
),
)
)
fig.show()
Similarly to this wonderful animation: https://plotly.com/python/visualizing-mri-volume-slices/
I would like to slice up my data to isosurfaces with respect to any x,y,z coordinates.
As in the example they use images, I could not wrap my head around to create the same with my raw data.
Thank you in advance.

Different color in hvplot.box

The following code generates the linked image. It generates mostly what I want but I would like the box color to be different between Real and Preds. How would I do that with Holoviews or Hvplot?
import hvplot.pandas
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(20), columns=['Value'])
df['Source'] = ['Preds'] *10 +['Real'] * 10
df['Item'] = ['item1'] *5 + ['item2']*5 + ['item1'] *5 + ['item2']*5
df.hvplot.box(y='Value', by=['Item', 'Source'])
I would like the first graph of this image to be in the style of the second
You can do it by setting the color and cmap parameter:
df.hvplot.box(
y='Value',
by=['Item', 'Source'],
color='Source',
cmap=['blue', 'orange'],
legend=False,
)
Or by setting .opts(box_color):
df.hvplot.box(
y='Value',
by=['Item', 'Source'],
legend=False,
).opts(
box_color='Source',
cmap='Category20',
)
See also this SO question: Holoviews color per category
More info on choosing particular colors for plots:
http://holoviews.org/user_guide/Styling_Plots.html
http://holoviews.org/user_guide/Colormaps.html

Change the facecolor of boxplot in pandas

I need to change the colors of the boxplot drawn using pandas utility function. I can change most properties using the color argument but can't figure out how to change the facecolor of the box. Someone knows how to do it?
import pandas as pd
import numpy as np
data = np.random.randn(100, 4)
labels = list("ABCD")
df = pd.DataFrame(data, columns=labels)
props = dict(boxes="DarkGreen", whiskers="DarkOrange", medians="DarkBlue", caps="Gray")
df.plot.box(color=props)
While I still recommend seaborn and raw matplotlib over the plotting interface in pandas, it turns out that you can pass patch_artist=True as a kwarg to df.plot.box, which will pass it as a kwarg to df.plot, which will pass is as a kwarg to matplotlib.Axes.boxplot.
import pandas as pd
import numpy as np
data = np.random.randn(100, 4)
labels = list("ABCD")
df = pd.DataFrame(data, columns=labels)
props = dict(boxes="DarkGreen", whiskers="DarkOrange", medians="DarkBlue", caps="Gray")
df.plot.box(color=props, patch_artist=True)
As suggested, I ended up creating a function to plot this, using raw matplotlib.
def plot_boxplot(data, ax):
bp = ax.boxplot(data.values, patch_artist=True)
for box in bp['boxes']:
box.set(color='DarkGreen')
box.set(facecolor='DarkGreen')
for whisker in bp['whiskers']:
whisker.set(color="DarkOrange")
for cap in bp['caps']:
cap.set(color="Gray")
for median in bp['medians']:
median.set(color="white")
ax.axhline(0, color="DarkBlue", linestyle=":")
ax.set_xticklabels(data.columns)
I suggest using df.plot.box with patch_artist=True and return_type='both' (which returns the matplotlib axes the boxplot is drawn on and a dictionary whose values are the matplotlib Lines of the boxplot) in order to have the best customization possibilities.
For example, given this data:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(
data=np.random.randn(100, 4),
columns=list("ABCD")
)
you can set a specific color for all the boxes:
fig,ax = plt.subplots(figsize=(9,6))
ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax)
for patch in props['boxes']:
patch.set_facecolor('lime')
plt.show()
you can set a specific color for each box:
colors = ['green','blue','yellow','red']
fig,ax = plt.subplots(figsize=(9,6))
ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax)
for patch,color in zip(props['boxes'],colors):
patch.set_facecolor(color)
plt.show()
you can easily integrate a colormap:
colors = np.random.randint(0,10, 4)
cm = plt.cm.get_cmap('rainbow')
colors_cm = [cm((c-colors.min())/(colors.max()-colors.min())) for c in colors]
fig,ax = plt.subplots(figsize=(9,6))
ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax)
for patch,color in zip(props['boxes'],colors_cm):
patch.set_facecolor(color)
# to add colorbar
fig.colorbar(plt.cm.ScalarMappable(
plt.cm.colors.Normalize(min(colors),max(colors)),
cmap='rainbow'
), ax=ax, cmap='rainbow')
plt.show()

Categories

Resources