基于附近点密度的 matplotlib hexbins 中的十六进制大小 [英] Hex size in matplotlib hexbins based on density of nearby points

查看:35
本文介绍了基于附近点密度的 matplotlib hexbins 中的十六进制大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码,产生下图

将 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆