2

Following the example code provided in this answer, I was able to plot my data using Python Matplotlib's bar3d function to obtain a stacked bar plot. The figure is shown below (plot (a)). My data are organized in four columns (1-D arrays): magnitude, distance, epsilon, and data (contribution to hazard). Each data point is associated to a magnitude, distance, and epsilon value. For each epsilon value (colored legend) I created separated bar plots of data as a function of magnitude and distance and stacked them on top of each other.

enter image description here

The plot shows the data correctly. The main issue is Matplotlib's 3-D rendering, which randomly overlaps bar segments depending on the perspective, making them look physically incorrect (highlighted with black circles in plot (b)). In most of the perspective angles there is still a few bars incorrectly overlapping. Unfortunately, this problem hasn't been solved yet, according to Matplotlib's documentation here.

For this reason, I'm forced to look for alternatives, and I'd appreciate some help to find the most convenient one:

  1. Matlab: I haven't been successful with the bar3 function to replicate this plot. The closest solution I've found is the stacked_bar3 function developed and explained in this MathWorks blog. However, in this formulation I haven't been able to use the respective magnitudes and distances as the anchor points for the bars in the horizontal axes. These points are set just as the number of samples in each direction. If I can find a solution to this (hopefully avoiding the manual label replacement in the plot with 'TickLabels'), I'll likely use this option.

Edit: The example Matlab code below shows the problem to which I can't find the solution yet (use mag and dist values in each axis, after using the stacked_bar3 function):

% Create random data (equivalent to single-epsilon array in my data):
data = randi(10, [30 37 1]);

% Arrays that I want to use in the horizontal axes:
dist = 10:20:590;   % Distance (length of 30)
mag = 4.55:0.1:8.15;   % Magnitude (length of 37)

% Create plot using custom-made function:
h = stacked_bar3(data);
xlabel('Magnitude (Mw)'); ylabel('Distance (km)')

The resulting figure is shown below, with the default values on the horizontal axes: enter image description here

  1. Python Mayavi: This library has good 3-D rendering support. However, the inability to show the bar plot within a detailed reference axis system (as in the attached figure) made me desist in the early stages of learning it.
  2. Microsoft Excel: This program can create a 3-D bar plot without any rendering issue after reorganizing the data (of a single epsilon) as a pivot table. However, I haven't been able to create a stacked 3-D bar plot for multiple epsilons like the one shown in the figure. Maybe someone knows a workaround for this one.
Carlos Herrera
  • 165
  • 1
  • 1
  • 7
  • I think MATLAB can definetly do the job. Can you elaborate on why you have not been able to use the blog examples for your case? I see no clear difference, and I don't fully understand your explanation. Do you just want this? https://stackoverflow.com/questions/28991376/how-to-set-x-and-y-values-when-using-bar3-in-matlab . A different way is to just provide your own `ticks` and `tickslabels` – Ander Biguri Aug 02 '23 at 09:20
  • @AnderBiguri yes, with Matlab I'm very close, just this detail is still unsolved. The solution you shared works perfectly with "bar3". But the function "stacked_bar3" in the blog has a different type of output when get(h, 'XData') is called. Because it builds polygons one by one (vertices, faces, etc), the same method cannot be used. I added a simple example to my question, it can be used with the "stacked_bar3" function as it is in the blog. – Carlos Herrera Aug 02 '23 at 19:30
  • Stacked bars are a terrible form of data visualization, and 3D plots (any type) are terrible too. If your goal is to obscure your data, then go ahead. Otherwise, come up with a 2D representation that communicates the data properly to your audience. – Cris Luengo Aug 03 '23 at 01:31

0 Answers0