我正在绘制带有许多数据点的几个散点图。在某个点上,一半的图只是纯色的,您不能很好地看到浓度。因此,我想将数据“投影”到轴上并显示直方图。
我写了一个小函数来做到这一点。对于轴ax
上的图,它绘制了熊猫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方块毁了我……
最佳答案
我不完全知道失败的原因,我可以想象这个问题与未定义对数刻度的范围小于0的数据有关。
无论如何,您都需要手动设置图的极限,
ax.set_yscale('log')
ax.set_ylim(1,None)
可能您想改用
symlog
标度。ax.set_yscale('symlog')
在这种情况下,无需进行极限调整。
关于python - matplotlib:具有对数刻度的共享轴上的不可读散点图和直方图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49268558/