matplotlib:共享轴上不可读的散点图和直方图,其中包含logscale

时间:2018-03-14 01:46:22

标签: python matplotlib

我正在绘制一些带有大量数据点的散点图。在某些时候,一半的情节只是纯色,你不能很好地看到密度。所以我想"项目"数据到轴上并显示直方图。

我写了一个小功能。对于轴ax上的绘图,它绘制了pandas DataFrame column_x的字段column_yframe的字段。如果给出了one_track_frame,那么它也会被绘制。要添加标题和标签等,可以使用lambda对象作为参数传递ax

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import pandas as pd

def projection_plot(ax, frame, column_x, column_y, frame_one_track=None, commands=None, bins=100):
    ax.scatter(frame[column_x], frame[column_y], label="one track", marker='x')

    divider = make_axes_locatable(ax)
    ax_hist_x = divider.append_axes("top", 1.2, pad=0.1, sharex=ax)
    for tl in ax_hist_x.get_xticklabels():
        tl.set_visible(False)
    ax_hist_x.hist(frame[column_x], bins=50)

    ax_hist_y = divider.append_axes("right", 1.2, pad=0.1, sharey=ax)
    for tl in ax_hist_y.get_yticklabels():
        tl.set_visible(False)
    ax_hist_y.hist(frame[column_y], orientation='horizontal', bins=bins)

    if frame_one_track is not None:
        ax.scatter(frame_one_track[column_x], frame_one_track[column_y], label="two tracks", marker='.')
        ax_hist_x.hist(frame_one_track[column_x], bins=bins)
        ax_hist_y.hist(frame_one_track[column_y], orientation='horizontal', bins=bins)

    if commands is not None:
        commands(ax)

如果我现在绘制一些随机数据,那么一切看起来都很正常。

df = pd.DataFrame(np.random.randn(1000, 3)*1000, columns=["a", "b", "c"])
cut = df["c"] < 20
frame1 = df[cut]
frame2 = df[~cut]

plt.figure(figsize=(6,6))
projection_plot(plt.subplot(), frame1, "a", "b", frame2, commands=lambda ax: (
    ax.legend(),
    ax.set_title("Random Values", y=1.4),
    ax.set_xlabel("column 0"),
    ax.set_ylabel("column 1")))

correct plot

如果我现在尝试将两个(或两个)轴的比例设置为log,则会出现问题并且图表变得不可读:

plt.figure(figsize=(6,6))
projection_plot(plt.subplot(), frame1, "a", "b", frame2, commands=lambda ax: (
    ax.legend(),
    ax.set_yscale('log'),
    ax.set_title("Random Values", y=1.4),
    ax.set_xlabel("column 0"),
    ax.set_ylabel("column 1")))

broken plot

在我的一些数据集中,它似乎工作正常,而对于其他数据集,它会像这些随机数据一样破坏。我该如何解决这个问题?

另外:由于我对Python比较陌生,这种编码风格是不是很好?通过多线lambda进行进一步配置?我觉得Ruby阻止了我......

1 个答案:

答案 0 :(得分:2)

我不确切知道失败的原因,我可以想象这个问题与低于0的数据有关,而没有定义对数比例。

在任何情况下,您都需要手动设置图表的限制,

ax.set_yscale('log')
ax.set_ylim(1,None)

enter image description here

可能您想要使用symlog比例。

ax.set_yscale('symlog')

在这种情况下,不需要进行限制调整。

enter image description here