From ddf092b618322722550e55086adabb7f47b0c937 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Thu, 27 Jun 2019 12:36:14 -0700 Subject: [PATCH] Fix png scaling --- news/2 Fixes/6344.md | 1 + package.json | 6 ++++++ src/client/common/types.ts | 1 + src/client/datascience/constants.ts | 3 ++- src/client/datascience/jupyter/jupyterServer.ts | 5 ++++- src/datascience-ui/plot/mainPanel.tsx | 14 +++----------- src/test/datascience/mockJupyterManager.ts | 2 +- 7 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 news/2 Fixes/6344.md diff --git a/news/2 Fixes/6344.md b/news/2 Fixes/6344.md new file mode 100644 index 000000000000..cba8947b076a --- /dev/null +++ b/news/2 Fixes/6344.md @@ -0,0 +1 @@ +Fix png scaling on non standard DPI. Add 'enablePlotViewer' setting to allow user to render pngs instead of svg files. diff --git a/package.json b/package.json index 1165bf3fef21..5fb3a5b967f9 100644 --- a/package.json +++ b/package.json @@ -1327,6 +1327,12 @@ "description": "Allow for connecting the Python Interactive window to a https Jupyter server that does not have valid certificates. This can be a security risk, so only use for known and trusted servers.", "scope": "resource" }, + "python.dataScience.enablePlotViewer": { + "type": "boolean", + "default": true, + "description": "Modify plot output so that it can be expanded into a plot viewer window.", + "scope": "resource" + }, "python.disableInstallationCheck": { "type": "boolean", "default": false, diff --git a/src/client/common/types.ts b/src/client/common/types.ts index f870f127d12e..72d053820108 100644 --- a/src/client/common/types.ts +++ b/src/client/common/types.ts @@ -319,6 +319,7 @@ export interface IDataScienceSettings { autoPreviewNotebooksInInteractivePane?: boolean; allowUnauthorizedRemoteConnection?: boolean; askForKernelRestart?: boolean; + enablePlotViewer?: boolean; } export const IConfigurationService = Symbol('IConfigurationService'); diff --git a/src/client/datascience/constants.ts b/src/client/datascience/constants.ts index 7cb7eaad4ff0..cd0a3c5de64d 100644 --- a/src/client/datascience/constants.ts +++ b/src/client/datascience/constants.ts @@ -148,7 +148,8 @@ export namespace Identifiers { export namespace CodeSnippits { export const ChangeDirectory = ['{0}', '{1}', 'import os', 'try:', '\tos.chdir(os.path.join(os.getcwd(), \'{2}\'))', '\tprint(os.getcwd())', 'except:', '\tpass', '']; export const ChangeDirectoryCommentIdentifier = '# ms-python.python added'; // Not translated so can compare. - export const MatplotLibInit = `import matplotlib\n%matplotlib inline\n${Identifiers.MatplotLibDefaultParams} = dict(matplotlib.rcParams)\n%config InlineBackend.figure_format = 'svg'`; + export const MatplotLibInitSvg = `import matplotlib\n%matplotlib inline\n${Identifiers.MatplotLibDefaultParams} = dict(matplotlib.rcParams)\n%config InlineBackend.figure_format = 'svg'`; + export const MatplotLibInitPng = `import matplotlib\n%matplotlib inline\n${Identifiers.MatplotLibDefaultParams} = dict(matplotlib.rcParams)\n%config InlineBackend.figure_format = 'png'`; } export namespace JupyterCommands { diff --git a/src/client/datascience/jupyter/jupyterServer.ts b/src/client/datascience/jupyter/jupyterServer.ts index e5cc6d58a16f..356a0a69c2b6 100644 --- a/src/client/datascience/jupyter/jupyterServer.ts +++ b/src/client/datascience/jupyter/jupyterServer.ts @@ -547,10 +547,13 @@ export class JupyterServerBase implements INotebookServer { await this.changeDirectoryIfPossible(this.launchInfo.workingDir); } + const settings = this.configService.getSettings().datascience; + const matplobInit = !settings || settings.enablePlotViewer ? CodeSnippits.MatplotLibInitSvg : CodeSnippits.MatplotLibInitPng; + // Force matplotlib to inline and save the default style. We'll use this later if we // get a request to update style await this.executeSilently( - CodeSnippits.MatplotLibInit, + matplobInit, cancelToken ); } catch (e) { diff --git a/src/datascience-ui/plot/mainPanel.tsx b/src/datascience-ui/plot/mainPanel.tsx index 975ff8d16b21..5605a62f992b 100644 --- a/src/datascience-ui/plot/mainPanel.tsx +++ b/src/datascience-ui/plot/mainPanel.tsx @@ -316,14 +316,6 @@ export class MainPanel extends React.Component this.postOffice.sendMessage(type, payload); } - private convertSizeToPixels(size: string) : number { - let multiplier = 1; - if (size.endsWith('pt')) { - multiplier = window.devicePixelRatio * 0.8866666; - } - return parseInt(size, 10) * multiplier; - } - private exportCurrent = async () => { // In order to export, we need the png and the svg. Generate // a png by drawing to a canvas and then turning the canvas into a dataurl. @@ -332,16 +324,16 @@ export class MainPanel extends React.Component if (doc) { const canvas = doc.createElement('canvas'); if (canvas) { - canvas.width = this.convertSizeToPixels(this.state.sizes[this.state.currentImage].width); - canvas.height = this.convertSizeToPixels(this.state.sizes[this.state.currentImage].height); const ctx = canvas.getContext('2d'); if (ctx) { const waitable = createDeferred(); - ctx.clearRect(0, 0, canvas.width, canvas.height); const svgBlob = new Blob([this.state.images[this.state.currentImage]], { type: 'image/svg+xml;charset=utf-8' }); const img = new Image(); const url = window.URL.createObjectURL(svgBlob); img.onload = () => { + canvas.width = img.width; + canvas.height = img.height; + ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0); waitable.resolve(); }; diff --git a/src/test/datascience/mockJupyterManager.ts b/src/test/datascience/mockJupyterManager.ts index a004878839bf..bc19b6840d03 100644 --- a/src/test/datascience/mockJupyterManager.ts +++ b/src/test/datascience/mockJupyterManager.ts @@ -100,7 +100,7 @@ export class MockJupyterManager implements IJupyterSessionManager { this.kernelSpecs.push({name: '0e8519db-0895-416c-96df-fa80131ecea0', dir: 'C:\\Users\\rchiodo\\AppData\\Roaming\\jupyter\\kernels\\0e8519db-0895-416c-96df-fa80131ecea0'}); // Setup our default cells that happen for everything - this.addCell(CodeSnippits.MatplotLibInit); + this.addCell(CodeSnippits.MatplotLibInitSvg); this.addCell('matplotlib.style.use(\'dark_background\')'); this.addCell(`matplotlib.rcParams.update(${Identifiers.MatplotLibDefaultParams})`); this.addCell(`%cd "${path.join(EXTENSION_ROOT_DIR, 'src', 'test', 'datascience')}"`);