質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

1908閲覧

Excelのグラフで近似曲線を透明化すると凡例の幅が自動調整されてしまう

zzzTKG

総合スコア7

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

1クリップ

投稿2020/08/24 23:38

編集2020/08/25 08:22

前提・実現したいこと

未だ研究室に属していない学生の身分ですのでレポート作成においてグラフを描画するには専らExcelを用いています.科学的なグラフではデータの位置を表すプロットの上を線が通るか通らないかということは大きな意味を持ちます.プロットより表面に線が来ていれば,それはそのプロットを確実に線が通っているということを意味し,逆に線がプロットの背面であればプロットを通っているとは言えず,近似的な意味を持ちます.しかし,Excelの近似曲線では系列より表面に描画されてしまい,"近似"ではなくなってしまいます.近似式を取得して近似曲線の系列を作り,マーカーなしにしてマーカー同士を結べば元のデータ系列のマーカー背面に位置させることができますが,科学実験で得られるデータは不規則なことやデータ間が広いことがしばしばあり,結ばれる線がヨレヨレに見えることがあります.理論的には近似曲線の系列を十分に細かくとってやれば滑らかに見えますが,どんな場合でも滑らかに見えるような区切り方となると無限に細かくせざるを得ません.当然そんなことをすればExcelもPCも悲鳴をあげます.そこで白抜きにしたいグラフを複製し,片方をマーカーのみ,もう片方をマーカー以外見えるようにして背景の塗りつぶしを無くしてぴったり重ねる方法を取ります.ぴったり重ねるにはグラフシートにマーカー以外を表示しているグラフを移動させ,そこにオブジェクトとしてマーカーのみのグラフを移動させて,最大化しています.
Rなら白抜きプロットは簡単にできるのですが,細かな体裁の調整はExcelの方が簡易で,VBAのコードもほぼ完成に近いためこのままExcelで成し遂げたいと思います.

発生している問題・エラーメッセージ

実は上記の手法をVBAで書くことは下記のコードでほぼ達成されています.現在問題となっているのは2つ以上の系列に近似曲線を描画し,凡例をグラフに重ねずに付けた上で下記のコードを実行すると,重ね合わせるグラフがずれてしまうことです.

原因はマーカーのみ表示のグラフの方で近似曲線を透明化して凡例に表示されている近似曲線も透明化された際,Excelが要らぬ気を利かせて凡例の幅を自動調整し,結果としてプロットエリアの幅が広くなり,マーカー以外表示のグラフとずれてしまうことです.「近似曲線を透明化しても凡例の近似曲線はそのまま」や「凡例の自動調整を無効にする」などこの問題の解決に妙案ありましたらご教授頂けますでしょうか.

該当のソースコード

VBA

1Option Explicit 2Sub Macro1() 3Dim PlotCha As ChartObject 4Dim LineCha As ChartObject 5Dim OriginSh As Worksheet 6Dim LineName As String 7'On Error Resume Next 8 Set LineCha = ActiveChart.Parent 9 LineName = LineCha.Name 10 Set OriginSh = ActiveSheet 11 If LineCha Is Nothing Then 12 MsgBox "白抜きプロットにするグラフを選んでから実行してください.", Title:="手順ミス" 13 Exit Sub 14 End If 15 LineCha.Chart.ChartArea.Copy 16 Range("A1").Select 17'Application.ScreenUpdating = False 18 OriginSh.Paste 19 Set PlotCha = Selection.Parent.Parent 20Dim PlotName As String 21 PlotName = LineName & "Copy" 22 PlotCha.Name = PlotName 23 With OriginSh.Shapes(LineName) 24 .Fill.Visible = msoFalse 25 .Line.Visible = msoFalse 26 End With 27 With LineCha.Chart 28Dim i As Long 29 For i = 1 To .FullSeriesCollection.Count 30 .FullSeriesCollection(i).MarkerStyle = xlMarkerStyleNone 31 Next i 32Dim ChartSh As String 33 ChartSh = "Sheet_" & LineName 34 .Location xlLocationAsNewSheet, Name:=ChartSh 35 End With 36 With OriginSh.Shapes(PlotName) 37 .Fill.Visible = msoFalse 38 .Line.Visible = msoFalse 39 End With 40 With PlotCha.Chart 41 .ChartArea.Format.TextFrame2.TextRange.Font.Fill.Transparency = 1 42 With .Axes(xlCategory) 43 .MajorGridlines.Format.Line.Visible = msoFalse 44 With .Format 45 .Line.Visible = msoFalse 46 .Fill.Visible = msoFalse 47 End With 48 End With 49 With .Axes(xlValue) 50 .MajorGridlines.Format.Line.Visible = msoFalse 51 With .Format 52 .Line.Visible = msoFalse 53 .Fill.Visible = msoFalse 54 End With 55 End With 56Dim j As Long 57 For j = 1 To .FullSeriesCollection.Count 58 With .FullSeriesCollection(j) 59Dim k As Long 60 For k = 1 To .Trendlines.Count 61 .Trendlines(k).Format.Line.Visible = msoFalse 62 Next k 63 End With 64 .FullSeriesCollection(j).Format.Fill.ForeColor.ObjectThemeColor = msoThemeColorBackground1 65 Next j 66 .Location xlLocationAsObject, Name:=ChartSh 67 End With 68 With Sheets(ChartSh).Shapes(PlotName) 69 .ScaleWidth 2.0341434821, msoFalse, msoScaleFromTopLeft 70 .ScaleHeight 2.2135414844, msoFalse, msoScaleFromTopLeft 71 'マクロの記録で得られた値ですが,この数値で良いのか,また,そもそもメソッドとして最大化の(マーカー以外表示グラフのサイズに合わせる)方法はないのか思案中です. 72 End With 73 ActiveChart.ChartArea.Copy 74 OriginSh.Pictures.Paste.Select 75'Application.ScreenUpdating = True 76End Sub

試したこと

凡例をグラフに重ねて表示しているものに上記コードを実行するとずれることはありません.また,凡例をグラフに重ねずに表示しているものに上記コードを実行後,グラフシートに作成されたマーカーのみのグラフの幅を少し狭めるとマーカーが正しい位置に来る点があります.これらのことから,やはり凡例の幅が縮まったことによってプロットエリアの幅が広くなり,重ねた際のズレを生み出していると考えられます.実際,適当なグラフを作って凡例をグラフに重ねずに表示し,近似曲線を手動で透明化するとプロットエリアが広くなる様子が見て取れます.

補足情報(FW/ツールのバージョンなど)

PC
MacBook Air,Intel Core i5-5250U,Boot CampによりWindows 10 Homeにて運用
Excel
2016 32ビット,バージョンは最新の状態

###追記1
回答を受けまして,「変更点」と示した部分に設定された色を取得して再設定するコードを付加しました.2020年8月25日17時01分

VBA

1Option Explicit 2Sub Macro1() 3Dim PlotCha As ChartObject 4Dim LineCha As ChartObject 5Dim OriginSh As Worksheet 6Dim LineName As String 7'On Error Resume Next 8 Set LineCha = ActiveChart.Parent 9 LineName = LineCha.Name 10 Set OriginSh = ActiveSheet 11 If LineCha Is Nothing Then 12 MsgBox "白抜きプロットにするグラフを選んでから実行してください.", Title:="手順ミス" 13 Exit Sub 14 End If 15 LineCha.Chart.ChartArea.Copy 16 Range("A1").Select 17'Application.ScreenUpdating = False 18 OriginSh.Paste 19 Set PlotCha = Selection.Parent.Parent 20Dim PlotName As String 21 PlotName = LineName & "Copy" 22 PlotCha.Name = PlotName 23 With OriginSh.Shapes(LineName) 24 .Fill.Visible = msoFalse 25 .Line.Visible = msoFalse 26 End With 27 With LineCha.Chart 28Dim i As Long 29 For i = 1 To .FullSeriesCollection.Count 30 .FullSeriesCollection(i).MarkerStyle = xlMarkerStyleNone 31 Next i 32Dim ChartSh As String 33 ChartSh = "Sheet_" & LineName 34 .Location xlLocationAsNewSheet, Name:=ChartSh 35 End With 36 With OriginSh.Shapes(PlotName) 37 .Fill.Visible = msoFalse 38 .Line.Visible = msoFalse 39 End With 40 With PlotCha.Chart 41 .ChartArea.Format.TextFrame2.TextRange.Font.Fill.Transparency = 0.99 42 With .Axes(xlCategory) 43 .MajorGridlines.Format.Line.Visible = msoFalse 44 With .Format 45 .Line.Visible = msoFalse 46 .Fill.Visible = msoFalse 47 End With 48 End With 49 With .Axes(xlValue) 50 .MajorGridlines.Format.Line.Visible = msoFalse 51 With .Format 52 .Line.Visible = msoFalse 53 .Fill.Visible = msoFalse 54 End With 55 End With 56Dim j As Long 57 For j = 1 To .FullSeriesCollection.Count 58 With .FullSeriesCollection(j) 59Dim k As Long 60 For k = 1 To .Trendlines.Count 61 With .Trendlines(k).Format.Line 62Dim LineCol As Variant 63 LineCol = .ForeColor 64 .ForeColor.RGB = RGB(LineCol Mod 256, Int(LineCol / 256) Mod 256, Int(LineCol / 256 / 256)) '変更点 65 .Transparency = 0.99 66 End With 67 Next k 68 End With 69 .FullSeriesCollection(j).Format.Fill.ForeColor.ObjectThemeColor = msoThemeColorBackground1 70 Next j 71 .Location xlLocationAsObject, Name:=ChartSh 72 End With 73 With Sheets(ChartSh).Shapes(PlotName) 74 .ScaleWidth 2.0341434821, msoFalse, msoScaleFromTopLeft 75 .ScaleHeight 2.2135414844, msoFalse, msoScaleFromTopLeft 76 End With 77 ActiveChart.ChartArea.Copy 78 OriginSh.Pictures.Paste.Select 79'Application.ScreenUpdating = True 80End Sub

###追記2
実際のグラフは動作確認用ですが以下のような感じです.2020年8月25日17時14分
データ
データ
マクロ実行前に選択されるグラフ
実行前グラフ
実行後にグラフシートにて背面に来るグラフ(マーカー以外表示グラフ)
マーカー以外表示グラフ
実行後にグラフシートにて表面に来るグラフ(マーカーのみ表示グラフ)
実行前グラフの近似曲線の色を取得して,同色を単色として再設定し,透明度99%に設定
マーカーのみ表示グラフ
グラフシートにて重なった2つのグラフ
完成グラフ
###追記3
追記1の通り一応望むものはごり押しでできました.今暫く回答受付中にしますので,これよりスマートな記述法がありましたらご教授願います.これが最適である場合にはその旨を教えて下さると幸いです.2020年8月25日17時18分
###追記4
追記2にて重なったグラフ(完成グラフ)を載せるのを忘れていましたので修正しました.2020年8月25日17時22分

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

radames1000

2020/08/25 00:01

実際のグラフを提示していただけませんか?
stdio

2020/08/25 00:41

少し理由が分からない点があります。 何故透過する必要があるのでしょうか? 表とグラフのシート分けるとかで工夫出来ますよね...
zzzTKG

2020/08/25 08:23

遅ればせながら実際のグラフを掲載しました.失礼しました.
zzzTKG

2020/08/25 08:26

追記2をご覧頂くとお分かりになるかと思われますが,上から重ねるため透過しなければ結局マーカーの上に線が見えてしまうのです.グラフ画像不備により混乱を招いてしまい,すみません.
zzzTKG

2020/08/25 08:31

それは前提欄にも記しました通り,近似曲線の式を取得して,近似曲線をデータ系列として作成して,近似曲線系列の上にデータ系列を持ってくる方法ですね.この方法は近似曲線系列が型崩れする場合があり,実用的ではありませんでした. また,変えられるのは系列同士の前後関係のみであり,近似曲線は常に全ての系列の上に表示されてしまいますので,近似曲線を近似曲線として白抜きプロットを作るためには2つのグラフを重ねるより他にないと考えられます.
jinoji

2021/02/21 13:26

凡例があるからずれるのだとすれば、凡例なしにしてしまえば、とか思ってしまうのは罪深き文系脳の性。 凡例なしグラフの重ね合わせの裏に、凡例のみのグラフを更に重ねる、とか考えたけど、全くスマートじゃないですね・・・
zzzTKG

2021/02/21 14:57

前者はやはりデータを分かりやすく提示することが目的であるグラフとしては避けたいですね. 後者ですが,凡例を入れる領域を凡例なしペアの方でズレなく空けられればいいのですが,グラフの式や軸ラベルなどの処理を考えると遠回りになるような気もします.スッキリとこれらを管理できれば有効な手法ではありそうです.
guest

回答3

0

自己解決

大分放置してしまいました...
追記3にお示しして以後,ご回答やご返信現れませんでしたので,追記1に示したコードにて自己解決と致します.
原因は凡例の線色がデフォルトでは自動設定であり,このまま透明度をいじると自動から単色に切り替わることで線の描画にズレが生じるようです.対策として,自動設定の色を取得し,単色として再設定することで自動調整を失くしました.
皆様ご助言ありがとうございました.

投稿2021/02/21 12:10

zzzTKG

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

(修正、載せ替え)
イメージ説明

VBA

1Sub tes01() 2 3Dim shName(2) As String, shpName 4Dim j, col, AreaWidth, AreaHeight 5Dim PlotAreaTop, PlotAreaLeft, PlotAreaWidth, PlotAreaHeight 6 7 With ActiveSheet.Shapes.AddChart.Chart 8 '.ChartType = xlXYScatter '分布図 9 .ChartType = xlLine '折れ線 10 11 .SeriesCollection.NewSeries 12 With .FullSeriesCollection(1) 13 .Name = "=Sheet2!$B$1" 14 .XValues = "=Sheet2!$A$2:$A$16" 15 .Values = "=Sheet2!$B$2:$B$16" 16 .MarkerStyle = 8 17 .MarkerSize = 5 18 .MarkerBackgroundColorIndex = 2 19 20 End With 21 22 .SeriesCollection.NewSeries 23 With .FullSeriesCollection(2) 24 .Name = "=Sheet2!$D$1" 25 .XValues = "=Sheet2!$A$2:$A$16" 26 .Values = "=Sheet2!$D$2:$D$16" 27 .MarkerStyle = 8 28 .MarkerSize = 5 29 .MarkerBackgroundColorIndex = 2 30 End With 31 .HasLegend = False 32 End With 33 shName(0) = ActiveSheet.Shapes(ActiveSheet.Shapes.Count).Name 34 35 'グラフの複写 36 shName(0) = ActiveSheet.Shapes(ActiveSheet.Shapes.Count).Name 37 ActiveSheet.Shapes(shName(0)).Copy 38 Range("F38").Select 39 ActiveSheet.Paste 40 shName(2) = ActiveSheet.Shapes(ActiveSheet.Shapes.Count).Name 41 42 '系統文字列変更、追加 43 With ActiveSheet.Shapes(shName(0)) 44 For j = 1 To .Chart.FullSeriesCollection.Count 45 With .Chart.FullSeriesCollection(j) 46 .Name = "系統" & j 47 .Trendlines.Add Type:=xlLinear, Forward:=0, Backward:=0, _ 48 DisplayEquation:=0, DisplayRSquared:=0, Name:="線形 (系統" & j & ")" 49 50 col = .Format.Line.ForeColor 51 With .Trendlines(1) 52 With .Format.Line 53 .Visible = msoTrue 54 .ForeColor.RGB = col 55 .DashStyle = msoLineSysDash 56 .Transparency = 0.4 57 End With 58 59 End With 60 With .Trendlines(1) 61 .DisplayEquation = True 62 .DisplayRSquared = True 63 End With 64 End With 65 Next 66 .Top = Range("F5").Top 67 .Left = Range("F5").Left 68 .Height = 300 69 .Width = 400 70 End With 71 'グラフの複写 72 ActiveSheet.Shapes(shName(0)).Copy 73 Range("F20").Select 74 ActiveSheet.Paste 75 shName(1) = ActiveSheet.Shapes(ActiveSheet.Shapes.Count).Name 76 77 78'shName(0) 79 With ActiveSheet.Shapes(shName(0)).Chart 80 .HasLegend = True 81 For j = 1 To .FullSeriesCollection.Count 82 83 With .FullSeriesCollection(j) 84 With .Format.Line 85 col = .ForeColor 86 .ForeColor.RGB = msoThemeColorBackground1 87 .Transparency = 1 88 End With 89 '.MarkerBackgroundColor = msoThemeColorBackground1 90 .MarkerForegroundColor = col 91 End With 92 Next 93 End With 94 95'shName(1) 96 With ActiveSheet.Shapes(shName(1)).Chart 97 For j = 1 To .FullSeriesCollection.Count 98 With .FullSeriesCollection(j) 99 .Format.Line.ForeColor.RGB = RGB(255, 255, 255) 100 .MarkerBackgroundColor = RGB(255, 255, 255) 101 .MarkerForegroundColor = RGB(255, 255, 255) 102 End With 103 Next 104 With .ChartArea 105 .Fill.Visible = msoFalse 106 .Format.Line.Visible = msoFalse 107 End With 108 With .PlotArea 109 .Format.Fill.Visible = msoTrue 110 .Format.Line.Visible = msoFalse 111 End With 112 With .Axes(xlValue) 113 With .Format.Line 114 .Visible = msoTrue 115 .ForeColor.ObjectThemeColor = msoThemeColorBackground1 116 .ForeColor.TintAndShade = 0 117 .ForeColor.Brightness = 0 118 .Transparency = 1 119 End With 120 End With 121 With .Axes(xlCategory) 122 With .Format.Line 123 .Visible = msoTrue 124 .ForeColor.ObjectThemeColor = msoThemeColorBackground1 125 .ForeColor.TintAndShade = 0 126 .ForeColor.Brightness = 0 127 .Transparency = 1 128 End With 129 End With 130 131 132 End With 133 134 135'shName(2)の加工 136 With ActiveSheet.Shapes(shName(2)).Chart 137 For j = 1 To .FullSeriesCollection.Count 138 With .FullSeriesCollection(j) 139 With .Format.Line 140 col = .ForeColor 141 .ForeColor.RGB = msoThemeColorBackground1 142 .Transparency = 1 143 End With 144 '.MarkerBackgroundColor = msoThemeColorBackground1 145 .MarkerForegroundColor = col 146 End With 147 Next 148 With .ChartArea 149 .Fill.Visible = msoFalse 150 .Format.Line.Visible = msoFalse 151 End With 152 With .PlotArea 153 .Format.Fill.Visible = msoFalse 154 .Format.Line.Visible = msoFalse 155 End With 156 With .Axes(xlCategory) 157 .Format.Fill.Visible = msoFalse 158 .Format.Line.Visible = msoFalse 159 .HasMajorGridlines = False 160 .HasMinorGridlines = False 161 .HasTitle = False 162 End With 163 164 With .Axes(xlValue) 165 .Format.Fill.Visible = msoFalse 166 .Format.Line.Visible = msoFalse 167 .HasMajorGridlines = False 168 .HasMinorGridlines = False 169 .HasTitle = False 170 End With 171 End With 172 173 174 'グラフエリアをそろえる 175 With ActiveSheet.Shapes(shName(0)) 176 AreaWidth = .Width 177 AreaHeight = .Height 178 179 PlotAreaTop = .Chart.PlotArea.Top + 10 180 PlotAreaLeft = .Chart.PlotArea.Left + 10 181 PlotAreaWidth = .Chart.PlotArea.Width 182 PlotAreaHeight = .Chart.PlotArea.Height 183 End With 184 'プロットエリアをそろえる 185 For Each shpName In shName() 186 With ActiveSheet.Shapes(shpName) 187 .Width = AreaWidth 188 .Height = AreaHeight 189 End With 190 With ActiveSheet.Shapes(shpName).Chart 191 .PlotArea.Top = PlotAreaTop 192 .PlotArea.Left = PlotAreaLeft 193 .PlotArea.Width = PlotAreaWidth 194 .PlotArea.Height = PlotAreaHeight 195 End With 196 Next 197 198 199'重ね合わせ 200 With ActiveSheet.Shapes(shName(1)) 201 .Top = Range("F5").Top '位置を設定 202 .Left = Range("F5").Left 203 .ZOrder msoBringForward 204 End With 205 With ActiveSheet.Shapes(shName(2)) 206 .Top = Range("F5").Top '位置を設定 207 .Left = Range("F5").Left 208 .ZOrder msoBringForward 209 End With 210 211End Sub 212

投稿2020/08/25 10:01

編集2020/08/27 17:03
sinzou

総合スコア392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zzzTKG

2020/08/25 10:16

それは近似曲線ではなく,マーカーのオプションから追加できるマーカーの線ですね.マーカー同士を結んでいるだけのコネクタです. グラフ要素として追加される近似曲線(Trendlinesで扱われる)はどうしても系列より表面に来てしまうと思うのですが...
guest

0

近似曲線の透明度を99%にしてみてはいかがでしょう。

投稿2020/08/25 00:08

radames1000

総合スコア1925

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zzzTKG

2020/08/25 07:58

双方に1%でも透明度がかかる時点で凡例幅が短くなり,ずれが生じました.そこで気づいたのですが,透明度を1%以上掛けた際に近似曲線の色が自動から単色に切り替わることで,凡例に表示されている近似曲線の長さが短くなり,凡例幅を狭めているようでした.普通は白黒基本ですので自動設定が任意設定(単色)に変わることの弊害はほぼ無視できるのですが,自動でも対応できるよう追記のコードで実現できました.自動設定の色を取得し,RGBで再設定してコピー元とコピー後の両グラフ間における差を無くしました.無理矢理感がありますのでより良いコード案がありましたらご教授願います.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問