【问题标题】:matplotlib scatter plotting with noncontiguous yaxis ticks with datatype as integermatplotlib 散点图,带有非连续 y 轴刻度,数据类型为整数
【发布时间】:2021-08-11 15:15:39
【问题描述】:

我的问题: 从数据帧中绘制 x 和 y 值时,如果我们将 y 值作为离散数字表示,id_number 或类别。如果我们使用散点图,它会给出线性间隔的 yaxis 刻度,根据我们原始值的间距,在绘制的值之间可能有很大的垂直间距。

我需要的是在散点图中针对时间事件 (xaxis) 绘制一些类别值(固定离散值),但表中的值只是整数而不是字符串。由于我对如何执行此操作没有任何深入的了解,因此以下是我所取得的成就,但修改了带有字符串值的原始表。这是我的测试数据(原始数据很大)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mtic
import matplotlib.category as mcat

np.random.seed(432987435)

nofpoints = 160

xval = np.arange(nofpoints)
disc = [ 200, 240, 250, 290 ]

yval = np.random.choice( disc , nofpoints)
yval_str = yval.astype(str)
yval , yval_str

cval = np.random.random( nofpoints )
df = pd.DataFrame( { 'xval': xval , 'yval':yval , 'cval': cval })
df_str = pd.DataFrame( { 'xval': xval , 'yval':yval_str , 'cval': cval })

使用通常的绘图方法

fig = plt.figure(dpi=128 , figsize=(12,6))
ax1 = fig.add_subplot(111) 
# here we are using the original dataframe(df), without any string field inside.
#ax1.grid(True)
ax1.scatter( 'xval' , 'yval' , data=df , marker='o', facecolor='None' , edgecolor='g')
plt.show()

这就是我们得到的 看到值之间的大间距,并且每个绘图点都不反对刻度值。 (我不想使用图例来显示使用颜色图的类别,因为它是为其他目的而保留的) 修改后的数据框以字符串为 yaxis 值

fig = plt.figure(dpi=128 , figsize=(12,6))
ax2 = fig.add_subplot(111) 
# dataframe used is modified one with a string field inside.
# as we can see the order is shuffled.
ax2.scatter( 'xval' , 'yval' , data=df_str , marker='o', facecolor='None' , edgecolor='k')
plt.show()

避免洗牌

fig = plt.figure(dpi=128 , figsize=(12,6))
ax3 = fig.add_subplot(111) 
# to maintain the same order and avoid shuffling we used matplotlib.category
#ax3.grid(True)
disc_str = [ str(x) for x in disc ]
units = mcat.UnitData(sorted(disc_str))
ax3.yaxis.set_units(units)
ax3.yaxis.set_major_locator( mcat.StrCategoryLocator(units._mapping))
ax3.yaxis.set_major_formatter( mcat.StrCategoryFormatter(units._mapping))
ax3.scatter( 'xval' , 'yval' , data=df_str , marker='o', facecolor='None' , edgecolor='y')
plt.show()

有什么办法可以做到,不修改原表,我的意思是把整数类别值绘制为y轴值。

【问题讨论】:

    标签: python pandas dataframe matplotlib timeline


    【解决方案1】:

    您可以通过将ax1.scatter 替换为seaborn.stripplot 来做到这一点:

    sns.stripplot(ax = ax1, data = df, x = 'xval', y = 'yval_str', marker = 'o', color = 'white', edgecolor = 'green', linewidth = 1)
    

    在您这样做之前,如果您希望 y 轴按特定顺序排列,您应该对 df 进行排序:

    df = pd.DataFrame({'xval': xval, 'yval': yval, 'yval_str': yval_str, 'cval': cval}).sort_values(by = 'yval', ascending = False)
    

    完整代码

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    np.random.seed(432987435)
    
    nofpoints = 160
    
    xval = np.arange(nofpoints)
    disc = [200, 240, 250, 290]
    
    yval = np.random.choice(disc, nofpoints)
    yval_str = yval.astype(str)
    
    cval = np.random.random(nofpoints)
    df = pd.DataFrame({'xval': xval, 'yval': yval, 'yval_str': yval_str, 'cval': cval}).sort_values(by = 'yval', ascending = False)
    
    fig = plt.figure(dpi = 128, figsize = (12, 6))
    ax1 = fig.add_subplot(111)
    sns.stripplot(ax = ax1, data = df, x = 'xval', y = 'yval_str', marker = 'o', color = 'white', edgecolor = 'green', linewidth = 1)
    plt.show()
    

    如果您想要完美水平对齐的点,您必须将jitter = False 传递给sns.stripplot

    sns.stripplot(ax = ax1, data = df, x = 'xval', y = 'yval_str', marker = 'o', color = 'white', edgecolor = 'green', linewidth = 1, jitter = False)
    

    【讨论】:

    • 谢谢..绘制的值仍然只是字符串,对吗?我想要的是从表中绘制整数值,最好不要将其转换为字符串。
    • 如果您在 y 轴上绘制 intfloat,则轴是连续的,因此轴上的标签将以数学方式隔开。如果您希望标签之间的间距与它们的数值无关,那么您必须将 y 轴值视为分类值;这就是你需要str的原因。
    • 此外,检查数据框:原始值存储为int'yval' 列中,用于绘图的值存储为'str' 在另一列'yval_str' 中,保留未触及的原始数据.如果不想修改数据框,可以将'yval_str' 保留为单独的list,而不是数据框列。
    • 可以将 'yval_str' 保留为不是数据框列,而是单独的列表。明白了。会检查的。
    猜你喜欢
    • 2021-11-07
    • 2020-06-26
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    相关资源
    最近更新 更多