3D MATLAB不同大小的粒子散点图

时间:2017-09-29 19:39:16

标签: matlab plot 3d scatter-plot particles

我正在寻找一种强大的3D绘图粒子方法,我有3D坐标和半径:

class PostComponent extends Component {
  componentWillMount() {
    const { postId } = this.props
    getComments(postId)
  }

  renderNumberOfCommets(postId) {
    const { comments } = this.props
    return _.map(comments, comment => {
      {
        JSON.stringify(comments)
      }
    })
  }

  renderPost() {
    const {
      postId,
      title,
      voteScore,
      author,
      category,
      timestamp,
      body,
      readirect,
      pushVotePost,
      comments,
    } = this.props
    const time = timeConverter(timestamp)
    console.log('comments')
    console.log(comments)
    return (
      <div key={postId}>
        <div className="">
          <ul className="">
            <li>
              <p>
                <span
                  className="fa fa-angle-up voteArrow"
                  onClick={() => pushVotePost('upVote', postId)}
                />
              </p>
            </li>
            <li className="votes">{voteScore}</li>
            <li>
              <span
                className="fa fa-angle-down voteArrow"
                onClick={() => pushVotePost('downVote', postId)}
              />
            </li>
          </ul>
        </div>
        <div className="">
          <Link to={`${category}`}>
            <span className="">{category}</span>
          </Link>
          {readirect ? (
            <Link to={`${category}/${postId}`}>
              <h3 className="">{title}</h3>
              <p>{body ? `${body}` : ''}</p>
              <p>Comments: {comments}</p>
              <footer className="">
                Writte by {author}, {time}
              </footer>
            </Link>
          ) : (
            <div>
              <h3 className="">{title}</h3>
              <p>{body ? `${body}` : ''}</p>
              <footer className="">
                Writte by {author}, {time}
                {/* TODO: Comments should go here in a numbered format. */}
                <p>Comments: {this.renderNumberOfCommets(postId)}</p>
              </footer>
            </div>
          )}
        </div>
      </div>
    )
  }

  render() {
    return <div>{this.renderPost()}</div>
  }
}

PostComponent.propTypes = {
  id: PropTypes.string,
  voteScore: PropTypes.number,
  title: PropTypes.string,
  author: PropTypes.string,
  category: PropTypes.string,
  timestamp: PropTypes.number,
}

const mapStateToProps = (state, ownProps) => {
  console.log('PostComponent, mapStateToProps ownProps')
  console.log(ownProps)
  return {
    comments: state.comments.comments,
  }
}

export default connect(mapStateToProps, { pushVotePost, getComments })(
  PostComponent
)

我尝试使用:

 x=[0 1 1 0 0 1 1 0]';
 y=[0 0 1 1 0 0 1 1]';
 z=[0 0 0 0 1 1 1 1]';
 radius=[0.1 0.5 0.1 1 1 0.4 0.6 0.2]';

问题:如何以保证相对大小和位置的保护的方式绘制粒子(当窗口大小被修改时,粒子看到它们的大小相应地用轴调整)?

基本上,我想得到以下图表(我使用Ovito获得,来自我生成的.xyz(文本)文件(它包含[x; y; z; radius]))在MATLAB中,有可能调整图形窗口的大小,仍然得到相对于粒子表观尺寸的正确轴刻度:)

3D plot of the particles, the color and the size of which represent the radius. Note that the size of the particles is computed that's to the radius.

2 个答案:

答案 0 :(得分:1)

fourth argumentscatter3以平方点为单位定义标记区域(1点= 1/72英寸),相对于图形/屏幕大小,因此与轴无关数据单位。如果要相对于位置数据定义粒子的半径(使得原点半径为1的粒子在x,y和z方向上跨越[-1 1]),则scatter3不是不去工作。

一种选择是使用sphere将每个粒子绘制为surf,如图here所示。以下是使用示例数据执行此操作的方法:

% Data and unit sphere surface coordinates:
x = [0 1 1 0 0 1 1 0].';
y = [0 0 1 1 0 0 1 1].';
z = [0 0 0 0 1 1 1 1].';
radius = [0.1 0.5 0.1 1 1 0.4 0.6 0.2].';
[xS, yS, zS] = sphere;

% Plot spheres:
for pt = 1:numel(x)
  surf(x(pt)+xS.*radius(pt), ...  % Shift and scale x data
       y(pt)+yS.*radius(pt), ...  % Shift and scale y data
       z(pt)+zS.*radius(pt), ...  % Shift and scale z data
       'EdgeColor', 'none');
  hold on;
end

% Modify figure and axes:
axis equal
set(gcf, 'Color', 'k');
set(gca, 'Color', 'k', 'Box', 'on', 'BoxStyle', 'full', ...
    'XColor', 'w', 'YColor', 'w', 'ZColor', 'w', 'GridColor', 'none');

这是产生的情节:

enter image description here

请注意,默认情况下,曲面会根据高度进行着色。如果要对它们进行不同的着色,可以修改曲面的CDataFaceColor属性。例如,您可以通过修改上面的surf调用来为每个曲面基于其半径值(将映射到当前颜色映射)赋予平面颜色:

surf(x(pt)+xS.*radius(pt), ...
     y(pt)+yS.*radius(pt), ...
     z(pt)+zS.*radius(pt), ...
     radius(pt).*ones(size(xS)), ...
     'FaceColor', 'flat', 'EdgeColor', 'none');

答案 1 :(得分:0)

好的发现了。感谢@gnovice(谢谢你的伴侣)。在下文中,每个粒子的颜色根据其半径来选择。

packing. Colors reflect the radius. 这是代码:

figure
[xS, yS, zS] = sphere;
cmap=parula(length(x));
radius_sort = sort(radius);
% Plot spheres:
for pt = 1:numel(x)
    cmap_ind = find(radius_sort == radius(pt));
  hs=surf(x(pt)+xS.*radius(pt), ...  % Shift and scale x data
       y(pt)+yS.*radius(pt), ...  % Shift and scale y data
       z(pt)+zS.*radius(pt), ...  % Shift and scale z data
       'EdgeColor', 'none');
       set(hs,'FaceColor',cmap(cmap_ind(1),:))
  hold on;
end

还可以添加以下命令来调整轴和图形颜色:

% Modify figure and axes:
axis equal
set(gcf, 'Color', 'k');
set(gca, 'Color', 'k', 'Box', 'on', 'BoxStyle', 'full', ...
    'XColor', 'w', 'YColor', 'w', 'ZColor', 'w', 'GridColor', 'none');