我正在绘制一些带有大量数据点的散点图。在某些时候,一半的情节只是纯色,你不能很好地看到密度。所以我想"项目"数据到轴上并显示直方图。
我写了一个小功能。对于轴ax
上的绘图,它绘制了pandas DataFrame column_x
的字段column_y
与frame
的字段。如果给出了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")))
如果我现在尝试将两个(或两个)轴的比例设置为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")))
在我的一些数据集中,它似乎工作正常,而对于其他数据集,它会像这些随机数据一样破坏。我该如何解决这个问题?
另外:由于我对Python比较陌生,这种编码风格是不是很好?通过多线lambda进行进一步配置?我觉得Ruby阻止了我......