You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于频率调整pyplot.hexbin中六边形相对大小的方法咨询

Adjusting Hexagon Size by Frequency in Matplotlib's Hexbin

Hey there! You’re spot on that matplotlib.pyplot.hexbin() doesn’t have a built-in parameter to make hexagon sizes proportional to their count/frequency—binsize only controls how the data is partitioned into bins, not the visual size of each hex. The approach you read about (size scaling with count) is totally doable, though; it just requires a little extra work to extract the bin data and plot it manually.

Here’s a step-by-step way to implement it:

1. Calculate Hexbin Bins First

First, run hexbin to compute the bin counts and their center coordinates. We won’t display the default hexbin plot, just use it to get the underlying data:

import matplotlib.pyplot as plt
import numpy as np

# Generate sample data (replace with your own dataset)
np.random.seed(42)
x = np.random.normal(0, 1, 1000)
y = np.random.normal(0, 1, 1000)

# Compute hexbin data without rendering the default plot
hb = plt.hexbin(x, y, gridsize=20, visible=False)
counts = hb.get_array()  # Extract frequency/count for each bin
centers = hb.get_offsets()  # Get (x,y) center coordinates of each hex bin

2. Plot Scaled Hexagons with scatter

Use plt.scatter() with a hexagon marker (marker='h'), and set the s (size) parameter to scale with the counts array. Tweak the scaling factor to fit your plot’s dimensions:

# Define a scaling factor (adjust this based on your data range)
size_scaler = 50

# Plot hexagons where size and color both map to frequency
plt.scatter(centers[:, 0], centers[:, 1], 
            s=counts * size_scaler,
            marker='h',
            c=counts,
            cmap='viridis',
            alpha=0.8)

# Add colorbar for context
plt.colorbar(label='Frequency')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Hexagons Scaled by Frequency')
plt.show()

3. Optional: Exact Hexagon Path Scaling

If you want hexagons that match the exact shape/orientation of hexbin (instead of the scatter marker), extract the path of a single hex and scale it based on counts. This is more verbose but gives perfect alignment:

from matplotlib.patches import PathPatch

# Get the path template for one hexagon from the hexbin object
hex_path = hb.get_paths()[0]

fig, ax = plt.subplots()
for center, count in zip(centers, counts):
    if count == 0:
        continue  # Skip empty bins to clean up the plot
    # Scale the hex path based on count (adjust the scaling term as needed)
    scaled_path = hex_path.transformed(
        plt.matplotlib.transforms.Affine2D().scale(np.sqrt(count)/3) +
        plt.matplotlib.transforms.Affine2D().translate(*center)
    )
    patch = PathPatch(scaled_path, color=plt.cm.viridis(count/max(counts)), alpha=0.8)
    ax.add_patch(patch)

# Set plot limits to match the original hexbin extent
ax.set_xlim(hb.get_extent()[0], hb.get_extent()[1])
ax.set_ylim(hb.get_extent()[2], hb.get_extent()[3])
plt.colorbar(plt.cm.ScalarMappable(norm=plt.Normalize(0, max(counts)), cmap='viridis'), label='Frequency')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Exact Scaled Hexagons by Frequency')
plt.show()

Key Notes

  • Using visible=False in hexbin prevents the default fixed-size hexes from cluttering your plot.
  • Using the square root of counts (in the path scaling example) helps avoid large bins overwhelming the plot—you can adjust this based on how dramatic you want the size difference to be.
  • The "Multivariate Hexagonal Binning" approach you referenced relies on this exact logic: tying both the size and color of hexes to their count, which makes high-density areas far more prominent than fixed-size hexbin plots.

内容的提问来源于stack exchange,提问作者L. Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:59:15