Центрировать 3D-бары по заданным позициям в matplotlib - PullRequest
0 голосов
/ 19 сентября 2018

Рассмотрим трехмерный столбчатый график с пользовательскими линиями сетки:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.ticker import MultipleLocator
# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import

fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.zaxis.set_major_locator(MultipleLocator(2))

nx = 10
ny = 10

colors = cm.tab20(np.linspace(0, 1, nx))
width = depth = 0.1

for x in np.arange(nx):
    for y in np.arange(ny):
        ax.bar3d(x, y, 0, width, depth, x+y, shade=False, color = colors[x], edgecolor = 'black')

plt.show()

3D bar plot example

Как можно расположить столбцы так, чтобы столбцы находились в центре, гделинии сетки пересекаются друг с другом в плоскости xy?

Я думаю о чем-то вроде

ax.bar3d(x+0.5*depth, y+0.5*width, ...)

, только мне не ясно, какое смещение использует matplotlib.Он должен работать для всех значений depth и width.

Для 2D-графиков есть аргумент для этого, align = 'center', но, похоже, он не работает для 3D.

1 Ответ

0 голосов
/ 19 сентября 2018

То, что вам кажется смещением координат, - это на самом деле просто проекция в сочетании с полями осей.Следовательно, даже если стержни правильно расположены в их центре, они выглядят смещенными, и это смещение зависит от размера осей, угла обзора и т. Д.

Решение этой проблемы в принципе дано в следующих вопросах и ответах: Удалениеполя осей на трехмерном графике

Вы бы отцентрировали столбцы, вычтя половину их ширины, и добавили патч, чтобы удалить поля по оси.Затем, установив нижний предел z равным 0, столбцы прикрепляются к сетке, и они выглядят по центру для любого угла обзора.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.ticker import MultipleLocator
from mpl_toolkits.mplot3d import Axes3D 
from mpl_toolkits.mplot3d.axis3d import Axis

def _get_coord_info_new(self, renderer):
    mins, maxs, cs, deltas, tc, highs = self._get_coord_info_old(renderer)
    correction = deltas * [0,0,1.0/4]
    mins += correction
    maxs -= correction
    return mins, maxs, cs, deltas, tc, highs
if not hasattr(Axis, "_get_coord_info_old"):
    Axis._get_coord_info_old = Axis._get_coord_info  
Axis._get_coord_info = _get_coord_info_new


fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.zaxis.set_major_locator(MultipleLocator(2))

nx = 10
ny = 10

colors = cm.tab20(np.linspace(0, 1, nx))
width = depth = 0.1

for x in np.arange(nx):
    for y in np.arange(ny):
        ax.bar3d(x-width/2., y-depth/2., 0, width, depth, x+y, shade=False, 
                 color = colors[x], edgecolor = 'black')

ax.set_zlim(0,None)

plt.show()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...