基于附近点密度的 matplotlib hexbins 中的十六进制大小 [英] Hex size in matplotlib hexbins based on density of nearby points
问题描述
我有以下代码,产生下图
将 numpy 导入为 npnp.random.seed(3)将熊猫作为pd导入导入matplotlib.pyplot作为pltdf = pd.DataFrame()df ['X'] = list(np.random.randint(100,size = 100))+ list(np.random.randint(30,size = 100))df['Y'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))df ['Bin'] = df.apply(lambda row:.如果row ['X']< 30和row ['Y']< 30 else .9,轴= 1)图, ax = plt.subplots(figsize=(10,10))plt.scatter(df ['X'],df ['Y'])
我使用hexbins绘制了数据图,如下所述
from matplotlib import cm图, ax = plt.subplots(figsize=(10,10))hexbin = ax.hexbin(df ['X'],df ['Y'],C = df ['Bin'],gridsize = 20,cmap = cm.get_cmap('RdYlBu_r'),edgecolors ='black')plt.show()
我想根据六边形所覆盖区域中绘制的点的密度来更改六边形的大小.例如,左下角的六边形(点密集的地方)将比其他地方的六边形(点稀疏的地方)大.有没有办法做到这一点?
我尝试了
您可能需要花一些时间来了解颜色映射.
将 numpy 导入为 npnp.random.seed(3)将熊猫作为pd导入导入matplotlib.pyplot作为plt从matplotlib.collections导入PatchCollection从 matplotlib.path 导入路径从 matplotlib.patches 导入 PathPatchdf = pd.DataFrame()df ['X'] = list(np.random.randint(100,size = 100))+ list(np.random.randint(30,size = 100))df['Y'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))df ['Bin'] = df.apply(lambda row:.如果row ['X']< 30并且row ['Y']< 30 else .9,轴= 1)#fig, ((ax1, ax2)) = plt.subplots(1, 2, sharex=True, sharey=True)ax1 = plt.scatter(df ['X'],df ['Y'])图,ax2 = plt.subplots(figsize=(10,10))hexbin = ax2.hexbin(df ['X'],df ['Y'],C = df ['Bin'],gridsize = 20,edgecolors ='black',cmap ='RdBu',reduce_C_function = np.bincount)#**def sized_hexbin(ax,hc):偏移量 = hc.get_offsets()orgpath = hc.get_paths()[0]verts = orgpath.vertices值 = hc.get_array()ma = values.max()补丁 = []对于 zip(offsets,values) 中的偏移量,val:v1 = verts*val/ma + 偏移路径 = 路径(v1,orgpath.codes)补丁=路径补丁(路径)补丁.附加(补丁)pc = PatchCollection(补丁,cmap ='RdBu',edgecolors ='黑色')pc.set_array(值)ax.add_collection(pc)hc.remove()size_hexbin(ax2,hexbin)cb = plt.colorbar(hexbin,ax = ax2)plt.show()要根据 df['bins'] 值绘制图表 -需要更改#**标记行中的reduce_C_function-hexbin = ax2.hexbin(df ['X'],df ['Y'],C = df ['Bin'],gridsize = 20,edgecolors ='black',cmap ='RdBu',reduce_C_function = np.sum)[![在此处输入图像描述][2]][2][1]:https://i.stack.imgur.com/kv0U4.png[2]:https://i.stack.imgur.com/mb0gD.png#图表的另一种变化:# 其中大小基于 bin 中的点数,颜色基于 df['bin'] 的值./还添加 if 条件以控制最小 hexbin 大小.将numpy导入为npnp.random.seed(3)将熊猫作为pd导入导入matplotlib.pyplot作为plt从matplotlib.collections导入PatchCollection从 matplotlib.path 导入路径从 matplotlib.patches 导入 PathPatch从 functools 导入部分mycmp ='coolwarm'df = pd.DataFrame()df ['X'] = list(np.random.randint(100,size = 100))+ list(np.random.randint(30,size = 100))df ['Y'] = list(np.random.randint(100,size = 100))+ list(np.random.randint(30,size = 100))df ['Bin'] = df.apply(lambda row:.如果row ['X']< 30和row ['Y']< 30 else .9,轴= 1)#fig, ((ax1, ax2)) = plt.subplots(1, 2, sharex=True, sharey=True)ax1 = plt.scatter(df['X'], df['Y'])无花果,ax2 = plt.subplots(figsize =(10,10))hexbin = ax2.hexbin(df ['X'],df ['Y'],C = df ['Bin'],gridsize = 15,edgecolors ='black',cmap = newcmp,reduce_C_function = np.bincount)hexbin2 = ax2.hexbin(df['X'], df['Y'], C=df['Bin'], gridsize=15,edgecolors='black',cmap= newcmp, reduce_C_function=np.mean)def sized_hexbin(ax,hc,hc2):偏移量 = hc.get_offsets()orgpath = hc.get_paths()[0]verts = orgpath.verticesvalues1 = hc.get_array()values2 = hc2.get_array()ma = values1.max()补丁 = []对于 zip(offsets,values1) 中的偏移量,val:# 添加最小尺寸条件如果(val/ma)<0.2:val_t = 0.2别的:val_t = val/mav1 =顶点* val_t +偏移路径 = 路径(v1,orgpath.codes)打印(路径)补丁=路径补丁(路径)补丁.附加(补丁)pc = PatchCollection(patches, cmap= newcmp) #edgecolors='black'pc.set_array(values2)ax.add_collection(pc)hc.remove()hc2.remove()size_hexbin(ax2,hexbin,hexbin2)cb = plt.colorbar(hexbin2, ax=ax2)plt.xlim((-5,100))plt.ylim((-5, 100))plt.show()
I've got the following code which produces the following figure
import numpy as np
np.random.seed(3)
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame()
df['X'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))
df['Y'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))
df['Bin'] = df.apply(lambda row: .1 if row['X'] < 30 and row['Y'] < 30 else .9, axis=1)
fig, ax = plt.subplots(figsize=(10,10))
plt.scatter(df['X'], df['Y'])
I graphed the data using hexbins, as noted below
from matplotlib import cm
fig, ax = plt.subplots(figsize=(10,10))
hexbin = ax.hexbin(df['X'], df['Y'], C=df['Bin'], gridsize=20, cmap= cm.get_cmap('RdYlBu_r'),edgecolors='black')
plt.show()
I'd like to change the size of the hexagons based on the density of the points plotted in the area that a hexagon covers. For example, the hexagons in the bottom left (where the points are compact) will be larger than the hexagons everywhere else (where the points are sparse). Is there a way to do this?
Edit: I tried this solution, but I can't figure out how to color the hexes based on df['Bin'], or how to set the min and max hex size.
from matplotlib.collections import PatchCollection
from matplotlib.path import Path
from matplotlib.patches import PathPatch
fig, ax = plt.subplots(figsize=(10,10))
hexbin = ax.hexbin(df['X'], df['Y'], C=df['Bins'], gridsize=20, cmap= cm.get_cmap('RdYlBu_r'),edgecolors='black')
def sized_hexbin(ax,hc):
offsets = hc.get_offsets()
orgpath = hc.get_paths()[0]
verts = orgpath.vertices
values = hc.get_array()
ma = values.max()
patches = []
for offset,val in zip(offsets,values):
v1 = verts*val/ma+offset
path = Path(v1, orgpath.codes)
patch = PathPatch(path)
patches.append(patch)
pc = PatchCollection(patches, cmap=cm.get_cmap('RdYlBu_r'), edgecolors='black')
pc.set_array(values)
ax.add_collection(pc)
hc.remove()
sized_hexbin(ax,hexbin)
plt.show()
You may want to spend sometime in understanding color mapping.
import numpy as np
np.random.seed(3)
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.path import Path
from matplotlib.patches import PathPatch
df = pd.DataFrame()
df['X'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))
df['Y'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))
df['Bin'] = df.apply(lambda row: .1 if row['X'] < 30 and row['Y'] < 30 else .9, axis=1)
#fig, ((ax1, ax2)) = plt.subplots(1, 2, sharex=True, sharey=True)
ax1 = plt.scatter(df['X'], df['Y'])
fig,ax2 = plt.subplots(figsize=(10,10))
hexbin = ax2.hexbin(df['X'], df['Y'], C=df['Bin'], gridsize=20,edgecolors='black',cmap= 'RdBu', reduce_C_function=np.bincount) #**
def sized_hexbin(ax,hc):
offsets = hc.get_offsets()
orgpath = hc.get_paths()[0]
verts = orgpath.vertices
values = hc.get_array()
ma = values.max()
patches = []
for offset,val in zip(offsets,values):
v1 = verts*val/ma + offset
path = Path(v1, orgpath.codes)
patch = PathPatch(path)
patches.append(patch)
pc = PatchCollection(patches, cmap= 'RdBu', edgecolors='black')
pc.set_array(values)
ax.add_collection(pc)
hc.remove()
sized_hexbin(ax2,hexbin)
cb = plt.colorbar(hexbin, ax=ax2)
plt.show()
To plot the chart based on df['bins'] values -
Need to change the reduce_C_function in #** marked line -
hexbin = ax2.hexbin(df['X'], df['Y'], C=df['Bin'], gridsize=20,edgecolors='black',cmap= 'RdBu', reduce_C_function=np.sum)
[![enter image description here][2]][2]
[1]: https://i.stack.imgur.com/kv0U4.png
[2]: https://i.stack.imgur.com/mb0gD.png
# Another variation of the chart :
# Where size is based on count of points in the bins and color is based on values of the df['bin']./ Also added if condition to control minimum hexbin size.
import numpy as np
np.random.seed(3)
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.path import Path
from matplotlib.patches import PathPatch
from functools import partial
mycmp = 'coolwarm'
df = pd.DataFrame()
df['X'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))
df['Y'] = list(np.random.randint(100, size=100)) + list(np.random.randint(30, size=100))
df['Bin'] = df.apply(lambda row: .1 if row['X'] < 30 and row['Y'] < 30 else .9, axis=1)
#fig, ((ax1, ax2)) = plt.subplots(1, 2, sharex=True, sharey=True)
ax1 = plt.scatter(df['X'], df['Y'])
fig,ax2 = plt.subplots(figsize=(10,10))
hexbin = ax2.hexbin(df['X'], df['Y'], C=df['Bin'], gridsize=15,edgecolors='black',cmap= newcmp , reduce_C_function=np.bincount)
hexbin2 = ax2.hexbin(df['X'], df['Y'], C=df['Bin'], gridsize=15,edgecolors='black',cmap= newcmp , reduce_C_function=np.mean)
def sized_hexbin(ax,hc,hc2):
offsets = hc.get_offsets()
orgpath = hc.get_paths()[0]
verts = orgpath.vertices
values1 = hc.get_array()
values2 = hc2.get_array()
ma = values1.max()
patches = []
for offset,val in zip(offsets,values1):
# Adding condition for minimum size
if (val/ma) < 0.2:
val_t = 0.2
else:
val_t = val/ma
v1 = verts*val_t + offset
path = Path(v1, orgpath.codes)
print(path)
patch = PathPatch(path)
patches.append(patch)
pc = PatchCollection(patches, cmap= newcmp) #edgecolors='black'
pc.set_array(values2)
ax.add_collection(pc)
hc.remove()
hc2.remove()
sized_hexbin(ax2,hexbin,hexbin2)
cb = plt.colorbar(hexbin2, ax=ax2)
plt.xlim((-5, 100))
plt.ylim((-5, 100))
plt.show()
这篇关于基于附近点密度的 matplotlib hexbins 中的十六进制大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!