如何在Holoviews热力图中为每个点指定自定义颜色(含透明度)
I wanted to generate a HeatMap in Holoviews where each point has custom transparency levels. Initially, I tried overlaying two HeatMap objects (one with reduced opacity, another filtered to show fully opaque points), but this resulted in an Overlay instead of a single HeatMap instance:
import pandas as pd import holoviews as hv hv.extension('bokeh') data = pd.DataFrame([(i, 97+j, i*j) for i in range(5) for j in range(5)], columns=['x', 'y', 'val']) data_filtered = data[(data.x < 3) & (data.y < 100)] hm_opts = dict(kdims=['x', 'y'], vdims=['val']) hm = hv.HeatMap(data, **hm_opts).opts(alpha=0.5) hm_filtered = hv.HeatMap(data_filtered, **hm_opts).opts() hm * hm_filtered
I also tried mapping each (x,y) coordinate to a hex color with built-in transparency and adding a color column to my DataFrame, but ran into issues: passing the color list to cmap treated it as a continuous color range, passing the column name threw errors, and using the color parameter made the chart fail to render entirely.
I did manage to get this working directly with the Bokeh backend, but wanted to use Holoviews for building interactive applications:
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource from bokeh.models.ranges import FactorRange source = ColumnDataSource(data=data) x_unique = data['x'].unique() y_unique = data['y'].unique() min_width = 110 min_height = 80 width = min_width + 25 * len(x_unique) height = min_height + 25 * len(y_unique) x_rect_width = 0.90 y_rect_width = 0.90 plot = figure( plot_width=width, plot_height=height, title='', x_range=FactorRange(*x_unique), y_range=FactorRange(*y_unique), x_axis_label='x', y_axis_label='y', ) plot.rect('x', 'y', height=y_rect_width, width=x_rect_width, source=source, color='color') plot.xgrid.grid_line_color = None plot.ygrid.grid_line_color = None show(plot)
Working Holoviews Solution
With help from @thomas-pedot, I found the proper way to achieve this with a single Holoviews HeatMap by binding the alpha value directly to a column in the DataFrame:
import pandas as pd import holoviews as hv hv.extension('bokeh') data = pd.DataFrame([(i, 97+j, i*j) for i in range(5) for j in range(5)], columns=['x', 'y', 'val']) # Add an alpha column with custom transparency values data = data.assign(alpha=((data.x < 3) & (data.y < 100)).replace({True: 1.0, False: 3/8})) # Define custom color levels and corresponding colors red = '#FF0000' yellow = '#FFFF00' green = '#00FF00' blue_violet = '#8A2BE2' max_count = data['val'].max() levels = [0, 1, max_count / 2, max_count - 1, max_count] colors = [green, yellow, red, blue_violet] # Include 'alpha' in the value dimensions hm_opts = dict(kdims=['x', 'y'], vdims=['val', 'alpha']) hm = hv.HeatMap(data, **hm_opts).opts( alpha=hv.dim('alpha'), # Bind alpha to the DataFrame column color_levels=levels, cmap=colors ) hm
Key Details:
- Add an
alphacolumn to your DataFrame with values between 0 (fully transparent) and 1 (fully opaque) - Include
alphain thevdimsparameter so Holoviews recognizes it as a value dimension - Use
hv.dim('alpha')in the options to dynamically map each point's transparency to the column value - Define custom color levels and a corresponding colormap to control the fill colors independently of transparency
内容的提问来源于stack exchange,提问作者iRave

