【问题标题】:Using Matplotlib with Django在 Django 中使用 Matplotlib
【发布时间】:2017-08-21 05:15:54
【问题描述】:

我使用 Django 构建了一个简单的 Web 应用程序,它读取 csv 文件并允许用户通过选择 X 和 Y 属性来绘制图形。

前端利用 AJAX 调用来调用后端方法,以使用 Python 的 Matplotlib 绘制图形。当图被异步调用时会出现问题,从而导致竞争条件:不同的图表被绘制到同一个图上。

为了解决这个问题,我为每个用户分配了随机的“id”,这样我就可以调用 matplotlib 来获得一个数字——所以每个用户都在不同的数字上绘图。

import matplotlib
import pandas as pd
matplotlib.use('agg')

#cm is an array containing 2 confusion matrices generated from http://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html
def plot_confusion_matrix(user_id, cm, classes, path,
                          normalize=False,
                          title='Confusion Matrix',
                          cmap=plt.cm.Blues):
    id = user_id + random.randint(1, 10000)
    fig = plt.figure(id)
    axis1 = fig.add_subplot(121)
    title1 = title + " (train)"
    title2 =title + " (test)"
    def plot_cm(cm, title):
        plt.imshow(cm, interpolation='nearest', cmap=cmap)
        plt.title(title)
        #plt.colorbar()
        tick_marks = np.arange(len(classes))
        plt.xticks(tick_marks, classes, rotation=45)
        plt.yticks(tick_marks, classes)
        thresh = cm.max() / 2.
        for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
            plt.text(j, i, cm[i, j],
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")

        plt.tight_layout()
        plt.ylabel('True label')
        plt.xlabel('Predicted label')
    plot_cm(cm=cm[0], title=title1)
    axis2 = fig.add_subplot(122)
    plot_cm(cm=cm[1], title=title2)
    plt.tight_layout()
    fig.savefig(path)
    plt.close(id)

但是,这并不能解决问题 -- 当用户一次绘制 3 个图时,这些图会相互重叠。

【问题讨论】:

  • 向我们展示你是如何绘制图形的,你使用坐标轴吗?
  • @RadekHofman 添加了完整的绘图代码。希望对您有所帮助!

标签: python ajax django matplotlib concurrency


【解决方案1】:

好的,尝试像这样直接绘制到您创建的轴上:

def plot_confusion_matrix(user_id, cm, classes, path,
                          normalize=False,
                          title='Confusion Matrix',
                          cmap=plt.cm.Blues):
    id = user_id + random.randint(1, 10000)
    fig = plt.figure(id)
    axis1 = fig.add_subplot(121)
    title1 = title + " (train)"
    title2 =title + " (test)"
    def plot_cm(cm, title, ax):
        ax.imshow(cm, interpolation='nearest', cmap=cmap)
        ax.set_title(title)
        #plt.colorbar()
        tick_marks = np.arange(len(classes))
        ax.set_xticks(tick_marks, classes, rotation=45)
        ax.set_yticks(tick_marks, classes)
        thresh = cm.max() / 2.
        for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
            ax.text(j, i, cm[i, j],
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")

        plt.tight_layout()
        ax.set_ylabel('True label')
        ax.set_xlabel('Predicted label')
    plot_cm(cm=cm[0], title=title1, axis1)
    axis2 = fig.add_subplot(122)
    plot_cm(cm=cm[1], title=title2, axis2)
    plt.tight_layout()
    plt.savefig(path)
    plt.close(id)

【讨论】:

  • 感谢您的帮助,但是当我尝试在轴本身上调用方法时,使用该代码会出现错误。除了 imshow(),其他所有方法都不能用于坐标轴对象。
  • 是的,我尝试更改它以使其正常工作,例如 xticks -> set_xticks。即使有这个set_ 它也不起作用?
  • ax.set_xticks(tick_marks, classes, rotation=45) 返回“意外的 arg 旋转”;删除“旋转”后,我收到错误“max() arg is an empty sequence”
  • 好的,rotationax.set_xticklabels(xlabels,.. rotation=45 而不是 set_xticks() 的参数,但是对于空序列我无能为力,似乎它从外面空出来了。你检查那里有什么吗?还是它以前工作过?你不是从plt 导入所有东西,所以你的cmplt.cm 之间存在混淆吗?
  • 对于 ax.set_xticklabels(tick_marks, classes, rotation=45),我正在尝试将 classes(字符串数组)分配给 tick_marks(int 数组),它指定标签的位置(类)。然而,使用斧头它只需要“标签”——有解决方法吗?
猜你喜欢
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 2013-08-20
  • 2018-08-23
相关资源
最近更新 更多