1

我正在尝试在 Chaco 堆积条形图中控制每个条形图和每个条形图段的颜色。

例如,运行 Chaco 的堆积条形图示例给出,

标准 Chaco 堆积条形图

我怎么把它变成这个怪物?

修改后的 Chaco 堆积条形图,每个条形图和线段都有自定义颜色

我可以看到 Chaco 有ColourMapped Scatter Plot,它允许控制每个点。我需要这种行为,但需要条形图。有没有一种快速的方法来做到这一点?

这是演示。生成默认 Chaco 堆积条形图的代码

"""
Simple example of a stacked bar chart
"""

# Major library imports
import numpy

# Enthought library imports
from enable.api import ComponentEditor
from traits.api import HasTraits, Instance
from traitsui.api import UItem, View

# Chaco imports
from chaco.api import LabelAxis, Plot, ArrayPlotData, ArrayDataSource


class PlotExample(HasTraits):

    plot = Instance(Plot)

    def _plot_default(self):
        index = numpy.array([1, 2, 3, 4, 5])
        series_a, series_b, series_c = (index * 10, index * 5, index * 2)
        # Stack them up
        series_c = series_c + series_b + series_a
        series_b = series_b + series_a

        plot_data = ArrayPlotData(index=index)
        plot_data.set_data("series_a", series_a)
        plot_data.set_data("series_b", series_b)
        plot_data.set_data("series_c", series_c)
        plot = Plot(plot_data)
        plot.plot(("index", "series_a"), type="bar", bar_width=0.8, color="auto")
        plot.plot(
            ("index", "series_b"),
            type="bar",
            bar_width=0.8,
            color="auto",
            starting_value=ArrayDataSource(series_a),
        )
        plot.plot(
            ("index", "series_c"),
            type="bar",
            bar_width=0.8,
            color="auto",
            starting_value=ArrayDataSource(series_b),
        )

        # set the plot's value range to 0, otherwise it may pad too much
        plot.value_range.low = 0

        # replace the index values with some nicer labels
        label_axis = LabelAxis(
            plot,
            orientation="bottom",
            title="Months",
            positions=list(range(1, 10)),
            labels=["jan", "feb", "march", "april", "may"],
            small_haxis_style=True,
        )

        plot.underlays.remove(plot.index_axis)
        plot.index_axis = label_axis
        plot.underlays.append(label_axis)

        return plot

    traits_view = View(
        UItem("plot", editor=ComponentEditor()), width=400, height=400, resizable=True,
    )


demo = PlotExample()

if __name__ == "__main__":
    demo.configure_traits()
4

1 回答 1

2

我会通过为堆积条形图中的每个段制作单独的条形图渲染器来解决这个问题。像这样的东西应该可以解决问题(对不起,非常冗长的for陈述):

"""
Simple example of a stacked bar chart
"""

# Major library imports
import numpy

# Enthought library imports
from enable.api import ComponentEditor
from traits.api import HasTraits, Instance
from traitsui.api import UItem, View

# Chaco imports
from chaco.api import LabelAxis, Plot, ArrayPlotData, ArrayDataSource


class PlotExample(HasTraits):

    plot = Instance(Plot)

    def _plot_default(self):
        index = numpy.array([1, 2, 3, 4, 5])
        series_a, series_b, series_c = (index * 10, index * 5, index * 2)
        # Stack them up
        series_c = series_c + series_b + series_a
        series_b = series_b + series_a

        plot_data = ArrayPlotData()
        for i, (index_val, series_a_val, series_b_val, series_c_val) in enumerate(zip(
            index, series_a, series_b, series_c
        )):
            plot_data.set_data(f"index_{i}", [index_val])
            plot_data.set_data(f"series_a_{i}", [series_a_val])
            plot_data.set_data(f"series_b_{i}", [series_b_val])
            plot_data.set_data(f"series_c_{i}", [series_c_val])

        plot = Plot(plot_data)

        for i, (index_val, series_a_val, series_b_val, series_c_val) in enumerate(zip(
            index, series_a, series_b, series_c
        )):
            plot.plot(
                (f"index_{i}", f"series_a_{i}"),
                type="bar",
                bar_width=0.8,
                color="auto",
            )
            plot.plot(
                (f"index_{i}", f"series_b_{i}"),
                type="bar",
                bar_width=0.8,
                color="auto",
                starting_value=ArrayDataSource([series_a_val]),
            )
            plot.plot(
                (f"index_{i}", f"series_c_{i}"),
                type="bar",
                bar_width=0.8,
                color="auto",
                starting_value=ArrayDataSource([series_b_val]),
            )

        # set the plot's value range to 0, otherwise it may pad too much
        plot.value_range.low = 0

        # replace the index values with some nicer labels
        label_axis = LabelAxis(
            plot,
            orientation="bottom",
            title="Months",
            positions=list(range(1, 10)),
            labels=["jan", "feb", "march", "april", "may"],
            small_haxis_style=True,
        )

        plot.underlays.remove(plot.index_axis)
        plot.index_axis = label_axis
        plot.underlays.append(label_axis)

        return plot

    traits_view = View(
        UItem("plot", editor=ComponentEditor()), width=400, height=400, resizable=True,
    )


demo = PlotExample()

if __name__ == "__main__":
    demo.configure_traits()

截图每个条形段具有不同颜色的堆叠条形图的简单示例

于 2022-01-20T15:53:32.030 回答