Тепловая карта Python с промежуточным цветом от процентиля

Вы можете использовать JRExporter для экспорта заполненного отчета в разные потоки и форматы.

JRExporter exporter = null;

exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outputStream);
exporter.exportReport();

Также обратите внимание, что есть и другие экспортеры:

exporter = new JRRtfExporter();
exporter = new JRHtmlExporter();

Вы можете найти больше экспортеров доступно здесь: http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/JRExporter.html

Все они должны принимать параметр OUTPUT_STREAM для контролировать назначение отчета.

0
задан MikeCC 13 July 2018 в 06:49
поделиться

3 ответа

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

К сожалению, морское дно не позволяет использовать пользовательские нормализации. Но создание тепловой карты с самим matplotlib одинаково легко, как показано в примере annotated_heatmap .

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors

class MidpointNormalize(colors.Normalize):
    def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
        self.midpoint = midpoint
        colors.Normalize.__init__(self, vmin, vmax, clip)

    def __call__(self, value, clip=None):
        # I'm ignoring masked values and all kinds of edge cases to make a
        # simple example...
        x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
        return np.ma.masked_array(np.interp(value, x, y))

data = {
        'row1': [90,95,99,50,50,45,0],
        'row2': [99,98,100,100,98,99,80],
        'row3': [98,97,99,100,96,95,98],
        'row4': [99,98,100,100,98,99,100]
        }
fig, ax = plt.subplots(figsize=(9, 4))
df = pd.DataFrame.from_dict(data,orient='index')

norm =  MidpointNormalize(midpoint=np.median(df.values))

im = ax.imshow(df.values, cmap="YlGnBu", norm=norm)
fig.colorbar(im)

# Loop over data dimensions and create text annotations.
textcolors = ["k" ,"w"]
threshold = 55
for i in range(len(df)):
    for j in range(len(df.columns)):
        text = ax.text(j, i, df.values[i, j],
                       ha="center", va="center", 
                       color=textcolors[df.values[i, j] > threshold])

plt.show()

2
ответ дан ImportanceOfBeingErnest 17 August 2018 в 13:31
поделиться
  • 1
    Спасибо @ImportanceOfBeingErnest, это был очень конструктивный ответ (снова). Я ценю помощь. – MikeCC 16 July 2018 в 14:04

После ссылки, предоставленной @StefanS, я придумал следующий способ регистрации моего собственного cmap, используя в моем случае медиану:

median = df.median().median()/100.0
c_red_yl_ = {'red':   ((0.0, 0.8, 0.8),
                   (median, 1.0, 1.0),
                   (1.0, 0.0, 0.0)),

         'green': ((0.0, 0.0, 0.0),
                   (median, 1.0, 1.0),
                   (1.0, 0.8, 0.8)),

         'blue':  ((0.0, 0.0, 0.0),
                   (median, 0.0, 0.0),
                   (1.0, 0.0, 0.0))
        }
plt.register_cmap(name='custom', data=cdict1)

Надеюсь, что это полезно для кого-то еще.

0
ответ дан MikeCC 17 August 2018 в 13:31
поделиться
  • 1
    Почему вы хотели бы это сделать? Matplotlib поставляется с множеством расходящихся цветовых карт ( matplotlib.org/examples/color/colormaps_reference.html ), которые имеют среднюю точку как четко идентифицируемый цвет (белый). Они также имеют более естественную интерполяцию через цветовое пространство, чем у вашей пользовательской карты. Почитайте об этом, почему вы, возможно, не захотите сделать свой собственный ( vis4.net/blog/2013/09/mastering-multi-hued-color-scales ) и скорее придерживаться предложения от цветного пивовара – Dan 16 July 2018 в 09:18
  • 2
    Да, цвета не лучший выбор, но вы можете использовать любой набор цветов @ Dan, кого это волнует? То, о чем я просил (и ответил), состоял в том, чтобы использовать медиану как среднюю точку в карте тепла. – MikeCC 16 July 2018 в 09:29
  • 3
    & quot; но вы можете использовать любой заданный набор цветов @Dan, кому это нужно? & quot ;. Конечно, вы можете делать все, что хотите. Но если вы хотите, чтобы люди могли понять, что вы создаете, стоит строить работу, которую другие уже сделали. Это не случай использования разных цветов, это пример того, как выполняется интерполяция, которой не управляет ваш код. – Dan 16 July 2018 в 11:15
  • 4
  • 5
    Я думаю, дело в том, что изменение самой цветовой карты обычно не является лучшим способом изменения отображения. Вместо этого может быть использована другая нормализация, как показано в моем ответе . – ImportanceOfBeingErnest 16 July 2018 в 13:19

Вы можете сделать что-то вроде этого:

import matplotlib as mpl
fig, ax = plt.subplots(figsize=(9, 4))
df = pd.DataFrame.from_dict(data,orient='index')
cmap1 = mpl.colors.ListedColormap(['y'])
sns.heatmap(df.round(), annot=True,ax=ax, cmap="YlGnBu")
sns.heatmap(df.round(), mask=df.round() > 50, cmap=cmap1, cbar=True)
plt.show()

1
ответ дан SudipM 17 August 2018 в 13:31
поделиться
  • 1
    Привет, SudipM, спасибо за идею, я играю с ней, но я не думаю, что это сработает для меня, мне не нравится идея иметь две цветовые полосы, я думаю, что это будет запутать. То, что я ищу, - это способ сделать интерполяцию цвета линейной по процентилю, а не по значению. Но опять же, спасибо за идею! – MikeCC 13 July 2018 в 08:25
Другие вопросы по тегам:

Похожие вопросы: